Bra*_*mir 4 c printf traversal file scanf
好的,我有一个文本文件database.txt.
每行都是具有以下格式的用户
"John Smith"| 4| 80.00| "123 Lollipop Lane"| "New Jersey"| "08080"
Run Code Online (Sandbox Code Playgroud)
当我尝试执行以下操作时:
database = fopen(fileName,"r");
while(fscanf(database,"%[^\n]", buffer) != EOF){
printf("ATTEMPT TO: Insert user %s\n\n", buffer);
if (insert_Customer(clients, create_Customer(buffer)) < 0){
printf("\nERROR: Failed to insert and create customer %s\n", buffer);
}
else printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
}
Run Code Online (Sandbox Code Playgroud)
它在第一行运行正常,将ENTIRE行发送到create_Customer(char*buffer)函数.出于某种原因,我不明白,在第一行之后它不断尝试发送"John Smith"而不是继续前进到下一行.我相信我的格式不正确,但我无法弄清楚如何完成我想要完成的工作,逐行读取此文件并将每行传递给create_Customer函数.
rky*_*ser 10
我认为你需要关闭\n你的模式.我看到了一堆带有相同第一行的滚动文本%[^\n],但是%[^\n]\n我看到了预期的输出.
但是,如果文件中的行超过缓冲区的行,则可能会遇到缓冲区空间不足的问题.结果
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE * database;
char buffer[30];
database = fopen("test.txt", "r");
if (NULL == database)
{
perror("opening database");
return (-1);
}
while (EOF != fscanf(database, "%[^\n]\n", buffer))
{
printf("> %s\n", buffer);
}
fclose(database);
return (0);
}
Run Code Online (Sandbox Code Playgroud)
> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
*** stack smashing detected ***: ./fscanf terminated
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
让我们修复代码,这样我们就不会超出缓冲区.我们通过改为%[^\n]\n来做到这一点%30[^\n]\n.这告诉fscanf它只能使用最大缓冲区大小 - 30.
#include <stdio.h>
int main(int argc, char * argv[])
{
FILE * database;
char buffer[30];
database = fopen("test.txt", "r");
if (NULL == database)
{
perror("opening database");
return (-1);
}
while (EOF != fscanf(database, "%30[^\n]\n", buffer))
{
printf("> %s\n", buffer);
}
fclose(database);
return (0);
}
Run Code Online (Sandbox Code Playgroud)
它看起来像是有效的!
> 12343456567856789
> zbasdflkjasdfkjklsdafjklas
> zxcvjkleryjkldhfg
> 1234567890123456789012341234
> 12345678901234567890123123asdf
> jklzxcv;jkl;eqwrtjklkzlcxvjkle
> qrt41234
Run Code Online (Sandbox Code Playgroud)
这就是我正在使用的测试文件.
12343456567856789
zbasdflkjasdfkjklsdafjklas
zxcvjkleryjkldhfg
1234567890123456789012341234
12345678901234567890123123asdfjklzxcv;jkl;eqwrtjklkzlcxvjkleqrt41234
Run Code Online (Sandbox Code Playgroud)
您正在使用的任何原因fscanf,而不是fgets?
如果您使用fgets,有一点需要注意,您可能想要删除该\n字符,因为它将作为字符串的一部分包含在内.
来自cplusplus.com fgets:
从流中读取字符并将它们作为C字符串存储到str中,直到读取(num-1)个字符或者到达换行符或文件结尾,以先发生者为准.
例:
/* fgets example */
#include <stdio.h>
int main()
{
FILE * database;
int res;
char buffer [100];
database = fopen(fileName,"r");
if (NULL == database) {
perror("opening database file");
return (-1);
}
/* while not end-of-file */
while (!feof(database)) {
/* we expect buffer pointer back if all is well, get out if we don't get it */
if (buffer != fgets(buffer, 100, database))
break;
/* strip /n */
int len = strlen(buffer);
if (buffer[len - 1] == '\n')
buffer[len - 1] = 0;
printf("ATTEMPT TO: Insert user %s\n\n", buffer);
if (insert_Customer(clients, create_Customer(buffer)) < 0)
printf("\nERROR: Failed to insert and create customer %s\n", buffer);
else
printf("\nSUCCESS: Inserted Customer %s\n\n", buffer);
}
/* a little clean-up */
fclose(database);
return (0);
}
Run Code Online (Sandbox Code Playgroud)