2014-11-02 40 views
0

我有以下C代碼,它將給程序的單詞寫入名爲「command.txt」的文件。如果單詞是「退出」程序結束,否則它打印該單詞並將其寫入文件。但是,如果單詞是「文件」,則通過使用函數getstring()獲取文件第一行的第一個單詞並繼續下一次循環迭代。然後在新一輪中使用這個單詞,代碼直接轉到「else」 - 分支,並打印出單詞並將其寫入文件。爲什麼C程序打印空行到文件?

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 


void getstring(char **p) { 
    char string[100]; 
    char *word = NULL; 
    FILE *file = fopen("command.txt", "r"); 
    fgets(string, 100, file); 
    word = strtok(string," \n"); 
    p[0] = word; 
    fclose(file); 
} 

void writetofile (char **strarr) { 
    FILE *file = fopen("command.txt", "a"); 
    fprintf(file, "%s\n", strarr[0]); 
    fclose(file); 
} 

int main(void) { 

    char line[100]; 
    char *word = NULL; 
    char *strarr[5]; 
    char **p = NULL; 
    int flag = 0, i; 

    while (1) { 
     if (flag == 1) { 
      flag = 0; 
     } 
     else { 
      printf("Give string: "); 
      fgets(line, 100, stdin); 
      word = strtok(line," \n"); 
      strarr[0] = word; 
     } 

     if (strcmp(strarr[0], "quit") == 0) { 
      break; 
     } 
     else if (strcmp(strarr[0], "file") == 0) { 
      p = strarr; 
      getstring(p); 
      flag = 1; 
      continue; 
     } 
     else { 
      printf("Text: %s\n", strarr[0]); 
      writetofile(strarr); 
     } 

     for (i=0; i<5; i++) { 
      strarr[i] = NULL; 
     } 
    } 

    return 0; 
} 

問題是這樣的:如果我輸入「文件」沒有寫入文件。例如,如果我給的話「你好」,「程序文件」和「世界」,然後退出程序打印輸出看起來是這樣的:

Give string: hello 
Text: hello 
Give string: file 
Text: hello 
Give string: world 
Text: world 
Give string: quit 

command.txt看起來是這樣的:

hello 

world 

所以,有一個空行應該是另一個「你好」。爲什麼是這樣?我在這裏丟失了一些明顯的東西,還是因爲指針被使用的方式?

+1

使用調試器檢查'strtok'調用後'word'指向的數據。在最後可能還有一個回車符('\ r')導致'strcmp'不匹配。 – 2014-11-02 17:49:38

+0

這些行:word = strtok(line,「\ n」); strarr [0] =單詞;總是將strarr [0]設置爲指向行[]數組I.E中的第一個字符。 &線[0]。所以簡單地說strarr [0] = line會更清楚; – user3629249 2014-11-02 18:22:36

+0

字符指針數組strarr [5]只有一個指針設置。 I.E. strarr [0],因此不需要將所有指針設置爲null的循環,也不需要用於char * strarr之外的任何其他用途。然後總是引用它作爲strarr。 char ** p = NULL並且所有對p服務器的引用都沒有用處,所以用strarr替換p的所有引用 – user3629249 2014-11-02 18:29:08

回答

3

一旦可能的問題是,你在getstring()返回一個指針到一個局部變量:

void getstring(char **p) { 
    char string[100]; 
    char *word = NULL; 
    ... 
    word = strtok(string," \n"); 
    p[0] = word;     //word points into string[] which is a local 
    ... 
} 

getstring()您的退貨後局部變量string[]是不是不再有效,因此訪問p[0]後來是未定義行爲。

若要解決此問題,請將單詞複製到固定緩衝區或爲返回字符串分配內存。

+0

這絕對是問題所在。 – 2014-11-02 18:15:20

+0

是的,就是這樣。非常感謝。 – JZ555 2014-11-03 11:48:34

0
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

char * getstring(void); 
void writetofile(char *); 

char * getstring() 
{ 
    static char fileString[100]; 
    memset(fileString, 0x00, sizeof(fileString)); 
    FILE *fp = fopen("command.txt", "r"); 
    if(NULL == fp) 
    { 
     perror("fopen"); 
     strcat(fileString, "ERROR: failed to open file: command.txt for read\n"); 
    } 
    else 
    { 
     if(NULL == fgets(fileString, 100, fp)) 
     { // then read error or file empty 
      perror("fgets"); 
      strcat(fileString, "I/O error occurred\n"); 
     } 
    } 
    fclose(fp); 
    return(&fileString[0]); 
} 

void writetofile (char *stringToWrite) 
{ 
    FILE *fp = fopen("command.txt", "a"); 
    if(NULL == fp) 
    { 
     perror("fopen"); 
    } 
    else 
    { 
     fprintf(fp, "%s\n", stringToWrite); 
     fclose(fp); 
    } 
} 

int main() 
{ 

    char line[100]; 

    while (1) 
    { 

     printf("Give string: "); 
     if(NULL == fgets(line, 100, stdin)) 
     { 
      perror("fgets"); 
     } 
     else 
     { // then successful read of string from user 

      if(NULL == strtok(line," \n")) 
      { 
       perror("strtok"); 
      } 
      else 
      { // else found/replaced trailing newline 

       if (strcmp(line, "quit") == 0) 
       { // then user wants to exit pgm 
        break; 
       } 

       // implied else 

       if (strcmp(line, "file") == 0) 
       { // then user wants to use first line of file. 
        // get/save first line from file 
        strcpy(line, getstring()); 
        printf("Text: %s", line); // note: line already contains '\n' 
        // append line to file 
        writetofile(line); 
       } 
       else 
       { 
        printf("Text: %s\n", line); 
        // append line to file 
        writetofile(line); 
       } 
      } 
     } 
    } 

    return(0); 
} 
+2

如果你解釋爲什麼你的答案能夠解決問題而不是簡單地傾銷一個大的代碼片段 – RobV 2014-11-02 23:56:13

+0

,我已經得到了解決方案來解決我自己的代碼中的問題。謝謝你的努力。 – JZ555 2014-11-03 11:55:30