【问题标题】:Checking line and then changing its data on a txt file检查行,然后在 txt 文件中更改其数据
【发布时间】:2015-01-02 17:49:43
【问题描述】:

所以,我有这个:

order.txt

file.txt;10;21:21

file2.txt;3;20:00

file2.txt;30;22:20

file4.txt;3;10:00

我希望用户提供所需的行(1 到 3,取决于存在多少行),然后更改其内容。例如:

第 3 行

"文件名: file.txt"

"秒: 5"

"时间 HH:MM: 20:00"

输出/更改为 order.txt:

file.txt;10;21:21

file2.txt;3;20:20

file.txt;5;20:00

file4.txt;3;10:00

如您所见,第三行发生了变化。为此,我尝试了以下方法:

变量

FILE* orderFile;
FILE* contentFile;
char fileName[50];
char timeValue[10];
int seconds;
char orderNameFile[50];
char orderTimeFile[50];
int orderSecondsFile;
int count = 0;
int i = 0;
int line;
int position;

代码

/* This will show the content on it with the number of the line behind */
orderFile = fopen("order.txt","r+");
                
printf("\n");

while(fscanf(orderFile," %49[^;];%d; %49[^\n]",fileName,&seconds,timeValue) == 3)
{
    i++;
    printf("[%d] %s;%d;%s\n",i,fileName,seconds,timeValue);
}

printf("\n");

rewind(orderFile);
/* ******************************************************************* */

/* This will ask which line he wants to change */
do{

    printf("Choose the line you want to change\n");
    printf("[Line] ");
    scanf("%d",&line);
    printf("\n");

    if(line > i)
    {
         printf("That line does not exist\n\n");
    }

}while(line > i || line < 1);
/* ******************************************* */

/* This will ask for the file name, seconds and time in HH:MM */
printf("Insert the name of the file\n");
printf("[Name] ");
getchar();
scanf("%s",&orderNameFile);

printf("Insert the presentation time in seconds\n");
printf("[Time in seconds] ");
scanf("%d",&orderSecondsFile);

printf("Insert the hour it starts\n");
printf("[Time in HH:MM (Hour:Minutes)] ");
getchar();
scanf("%s%",&orderTimeFile);
/* ******************************************* */

/* This is what is supposed to edit the line I want but does not work */
while(fscanf(orderFile," %49[^;];%d; %49[^\n]",fileName,&seconds,timeValue) == 3)
{
    count++;

    if(count == line)
    {
        position = ftell(orderFile);
        fseek(orderFile, position, SEEK_SET);
        fprintf(orderFile,"%s;%d;%s",orderNameFile,orderSecondsFile,orderTimeFile);
        break;
    }
}
*/ ****************************************************************** */

fclose(orderFile);

我想要使用第一个示例的输出:

file.txt;10;21:21

file2.txt;3;20:20

file.txt;5;20:00

file4.txt;3;10:00

输出它使用第一个示例@EDITED:

file.txt;10;21:21

file2.txt;3;20:00

file2.txt;30;22:20file.txt;5;20:00

file4.txt;3;10:00

你有什么想法吗?

【问题讨论】:

  • 这似乎是与您的变量linha 相关的问题。我看不到它的任何定义,所以我很难判断问题出在哪里。但我想第一个问题是 fscanf 在最后一个循环中读取该行,将光标移动到文件中,然后您尝试重写该行,重写它之后的数据。您需要将光标返回到行首。
  • 问题与this one 非常相似。 My answer 在这里也很重要。
  • 对不起,我把所有的东西都翻译成了英文,linha = line。如何将光标放回行首?我只知道如何输入第一行..会检查你的答案。
  • @Ran 您可以在每次 while 迭代之前使用ftell 将位置存储在文件中(例如,在第一次运行声明之前,然后在进行计数时)。当您进入if (count == line) 时,您将使用 fseek(orderFile, positionFromFtell, SEEK_SET)。此外,最好打破 if 主体中的 while 循环,向读者发出明确的信号,即它只运行一次。
  • 可以尝试复制另一个文件,但不想有很多 txt 文件。而且我们还不知道数据库,我只有 2 天的时间来完成这个。在“工作”项目中,它也要求保存在文件中。 Alegnem,关于如何将“光标”移回来有什么建议吗?

标签: c file line edit


【解决方案1】:

写入临时文件然后删除原始文件并将临时文件重命名为原始文件的名称通常效果更好

FILE *temp = fopen ( "temp", "w");
/* This is what is supposed to edit the line I want but does not work */
while(fscanf(orderFile," %49[^;];%d; %49[^\n]",fileName,&seconds,timeValue) == 3)
{
    count++;

    if(count == line)
    {
        fprintf(temp,"%s;%d;%s\n",orderNameFile,orderSecondsFile,orderTimeFile);
    }
    else 
    {
        fprintf(temp,"%s;%d;%s\n",filename,seconds,timeValue);
    }
}
fclose ( temp);
fclose ( orderFile);
remove ( "order.txt");// comment these two lines out until you are sure temp is correct
rename ( "temp", "order.txt");//that way you do not loose the original file

【讨论】:

  • 我应该做“temp.txt”对吗?也谢谢你,不知道可以这样做(删除和重命名)
  • @Ran,事实上你应该使用像mkstemp这样的随机文件名生成函数之一,如果你想使用这种方法,不能保证没有其他文件具有相同的名称,所以要么检查文件在fopen 之前是否存在或使用其他目录,如您的操作系统默认临时目录,或使用我的解决方案。
  • 嗯,它说 remove("order.txt");不是函数或指针。我也有 stdio.h 包括在内。知道为什么吗?
【解决方案2】:

删除文件的内容是一项昂贵的操作,更好的处理方法是

  1. 以写入模式打开一个新文件
  2. 开始将之前文件的内容写入这个新文件。
  3. 一旦到达应该被替换的行,请确保忽略读取行并使用 fprintf() 将新行写入新文件

IMO 这是更容易和正确的方法。使用下面的线程作为参考

Delete a Line from a file in C Language

【讨论】:

    【解决方案3】:

    您必须存储这些行,然后将它们重写到文件中,可能会有更优雅/高效的解决方案,但对于一个简单的情况,这应该没问题,这里是代码

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        FILE* orderFile;
        char fileName[50];
        char timeValue[10];
        int seconds;
        char orderNameFile[50];
        char orderTimeFile[50];
        int orderSecondsFile;
        int count;
        int lineCount;
        int line;
        char lineContent[128];
        char fileLines[128][128];
    
        /* This will show the content on it with the number of the line behind */
        orderFile = fopen("order.txt", "r+");
        if (orderFile == NULL)
            return -1;
        lineCount = 0;
    
        while ((fgets(lineContent, sizeof(lineContent), orderFile) != NULL) && (lineCount < 128))
        {
            size_t length;
    
            length = strlen(lineContent);
            if (lineContent[length - 1] == '\n')
                lineContent[length - 1] = 0;
            if (sscanf(lineContent, " %49[^;];%d; %49[^\n]", fileName, &seconds, timeValue) == 3)
            {
                strcpy(fileLines[lineCount], lineContent);
                printf("[%d] %s;%d;%s\n", ++lineCount, fileName, seconds, timeValue);
            }
        }
        printf("\n");
    
        rewind(orderFile);
    
        /* This will ask which line he wants to change */
        do {
    
            printf("Choose the line you want to change\n");
            printf("[Line] > ");
    
            scanf("%d", &line);
    
            if ((line > lineCount) || (line < 1))
                 printf("That line does not exist\n\n");
        } while ((line > lineCount) || (line < 1));
    
        /* This will ask for the file name, seconds and time in HH:MM */
        printf("Insert the name of the file\n");
        printf("[Name] ");
    
        scanf("%49s", orderNameFile);
    
        printf("Insert the presentation time in seconds\n");
        printf("[Time in seconds] ");
    
        scanf("%d", &orderSecondsFile);
    
        printf("Insert the hour it starts\n");
        printf("[Time in HH:MM (Hour:Minutes)] ");
    
        scanf("%49s", orderTimeFile);
    
        /* This is what is supposed to edit the line I want but does not work */
        count = 0;
        while (++count < lineCount + 1)
        {
            if (count == line)
                fprintf(orderFile, "%s;%d;%s\n", orderNameFile, orderSecondsFile, orderTimeFile);
            else
                fprintf(orderFile, "%s\n", fileLines[count - 1]);
        }
        fclose(orderFile);
    
        return 0;
    }
    

    【讨论】:

    • 然而,这可能会将它插入到我不想要的地方。例如,我想在所选行中将“file1.txt;5;20:00”更改为“file.txt;4;20:00”。例如:有 4 行,我想将第 2 行编辑为不同的内容。在我的情况下,它没有并将其添加到文件的末尾。
    • @Ran 我稍后会回到你的问题,看看你想做什么很有趣,如果你能添加一些例子会很好。现在我有事要做,但我会在一个小时左右回来。
    • 此刻输出的例子现在结束了。我只需要删除我要插入的内容后面的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2016-02-13
    • 2012-12-21
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多