2014-11-02 43 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