#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main()
{
int n,maxweitht;
scanf("%d\n%d",&n,&maxweitht);//整數1、2
int p[n],w[n],index = 0;
char *str,*delim;
gets(str);//字串1
delim = strtok(str," ");
while(delim != NULL)
{
puts(delim);
delim = strtok(NULL," ");
}
//index = 0;
gets(str);//字串2
delim = strtok(str," ");
while(delim != NULL)
{
puts(delim);
delim = strtok(NULL," ");
}
}
這是我的程式碼,我打算依序輸入2個整數後輸入2個字串,但是輸入完2個整數後就跳出segmentation fault,我將main()前3行註解掉後,就能正確輸入及輸出,請問問題出在哪呢?
1.原本char *str
只宣告一個「指標」,並沒有宣告保留「記憶體的空間」
然後gets(str)
就有可能去蓋掉別的變數的記憶體空間
2.很久之前就不建議使用 gets 這個指令,可能得換本新一點的書
程式修改如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STRLEN 100
main()
{
int n,maxweitht;
scanf("%d\n%d\n",&n,&maxweitht);//整數1、2
int p[n], w[n], index=0;
char str[STRLEN], *delim;
fgets(str, STRLEN, stdin);//字串1
delim = strtok(str," ");
while(delim != NULL)
{
puts(delim);
delim = strtok(NULL," ");
}
//index = 0;
fgets(str, STRLEN, stdin);//字串2
delim = strtok(str," ");
while(delim != NULL)
{
puts(delim);
delim = strtok(NULL," ");
}
}
以下是能正常執行的 code,僅供參考。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int n = 0, maxWeight = 0;
// 讀取兩個整數。
scanf("%d\n%d", &n, &maxWeight);
int index = 0;
int p[n], w[n];
char str[n];
char *token = NULL;
// 讀取字串。
gets(str);
// 以空白切割字串。
token = strtok(str, " ");
while(token != NULL)
{
puts(token);
token = strtok(NULL, " ");
}
// 讀取字串。
gets(str);
token = strtok(str, " ");
while(token != NULL)
{
puts(token);
token = strtok(NULL, " ");
}
return 0;
}
我想會有問題的應該是以下三種形式:
char str1[10];
char *str2 = NULL;
char *str3 = "123";
str1 是一個字元陣列,佔據了記憶體 10 個 char 型態的記憶體空間。
str2 是一個指標,指標的用途是儲存記憶體空間的位址,由於初始化給了 NULL,因此 str2 目前指向的記憶體空間為空(暫無指向記憶體位址)。str2 實際佔據的記憶空間其實與「一個 char 型態的記憶體位址的空間」相同。
str3 也是一個指標,與 str2 不同的是:他的初始值是一個字串,所以 C 會根據字串的大小在記憶體空間中分配一個 3 個字元長度的陣列,並將 str3 這個指標指向的記憶體位址設為陣列的第一個元素!str3 實際佔據的記憶空間其實與「一個 char 型態的記憶體位址的空間」相同(跟 str2 一樣)。不同的部份是:str3 的狀況下,新增了長度為 3 的字元陣列,用來儲存 "123"。str2 的狀況下,沒有從記憶體中拿取一段字元陣列的空間!
這就是為什麼你原本用 char *str; 會出問題的原因,因為 str 只是用於存放記憶體位址,但卻沒有從記憶體中保留一段字元陣列的空間,用於稍後的 gets 儲存字串用!
若改成 char str[n]; 就不同了!因為 str 會在記憶體中取得長度為 n 的字元陣列,之後 gets 讀進來的字串才有地方存放。
另外提醒你要注意一下 coding style 還有變數的 naming convension。