简体   繁体   English

为什么C程序将空白行打印到文件?

[英]Why C program prints blank line to file?

I have the following C code which writes words given to program to file called "command.txt". 我有以下C代码,它将给程序的单词写到名为“ command.txt”的文件中。 If word is "quit" program ends, else it prints the word and writes it to file. 如果单词是“ quit”,程序结束,否则它将打印单词并将其写入文件。 However, if the word is "file" it gets the first word on the first line of file by using function getstring() and continues to next loop iteration. 但是,如果单词是“ file”,则使用函数getstring()获取文件第一行中的第一个单词,并继续进行下一个循环迭代。 This word is then used on this new round and the code goes straight to "else"-branch and should print out the word and write it to file again. 然后在新的回合中使用该单词,代码直接转到“ else”分支,应打印出该单词并将其再次写入文件。

#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;
}

The problem is this: if I type in "file" nothing is written to the file. 问题是这样的:如果我键入“文件”,则什么都不会写入文件。 For example, if I give the words "hello", "file" and "world" and then quit the program the printout looks like this: 例如,如果我给单词“ hello”,“ file”和“ world”,然后退出程序,则打印输出如下:

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

command.txt looks like this: command.txt如下所示:

hello

world

So, there's an empty line where should be another "hello". 因此,有一个空行应在另一个“你好”。 Why is this? 为什么是这样? Am I missing something obvious here or is this because of the way pointers are used? 我在这里是否缺少明显的东西?或者是因为使用了指针?

Once possible issue is that you are returning a pointer to a local variable in getstring() : 可能的问题是,您正在返回指向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
    ...
}

After your return from getstring() the local variable string[] is not longer valid and thus accessing p[0] later on is undefined behaviour. getstring()返回后,局部变量string[]不再有效,因此以后访问p[0]是未定义的行为。

To fix this either copy the word into a fixed buffer or allocate the memory for the return string. 要解决此问题,可以将单词复制到固定缓冲区中,也可以为返回字符串分配内存。

#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 );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM