我一直在为我的CIS类做一个小练习,并且我对C用于从文件中读取的方法感到困惑.我真正需要做的就是逐行读取文件并使用从每行收集的信息进行一些操作.我尝试使用getline方法和其他没有运气的方法.我的代码目前如下:
int main(char *argc, char* argv[]){
const char *filename = argv[0];
FILE *file = fopen(filename, "r");
char *line = NULL;
while(!feof(file)){
sscanf(line, filename, "%s");
printf("%s\n", line);
}
return 1;
}
Run Code Online (Sandbox Code Playgroud)
现在我用sscanf方法得到一个seg错误,我不知道为什么.我是一名C总裁,只是想知道是否有一些我失踪的大事.谢谢
APr*_*mer 126
这么几行中存在很多问题.我可能会忘记一些:
所以
#include <stdio.h>
int main(int argc, char* argv[])
{
char const* const fileName = argv[1]; /* should check that argc > 1 */
FILE* file = fopen(fileName, "r"); /* should check the result */
char line[256];
while (fgets(line, sizeof(line), file)) {
/* note that fgets don't strip the terminating \n, checking its
presence would allow to handle lines longer that sizeof(line) */
printf("%s", line);
}
/* may check feof here to make a difference between eof and io failure -- network
timeout for instance */
fclose(file);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要从文件中读取一行,您应该使用以下fgets
函数:它从指定文件读取一个字符串,直到换行符或EOF
.
sscanf
在代码中的使用根本不起作用,因为您使用filename
格式字符串来读取line
常量字符串文字%s
.
SEGV的原因是你写入了指向的非分配内存line
.
假设您正在处理其他分隔符,例如\t
制表符,而不是\n
换行符.
分隔符的更通用方法是使用getc()
,一次抓取一个字符.
注意getc()
返回一个int
,这样我们就可以测试是否相等EOF
.
其次,我们定义一个line[BUFFER_MAX_LENGTH]
类型数组char
,以便BUFFER_MAX_LENGTH-1
在堆栈中存储最多字符(我们必须为\0
终结符字符保存最后一个字符).
使用数组避免了在堆上使用malloc
和free
创建正确长度的字符指针的需要.
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
/* get a character from the file pointer */
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
fprintf(stdout, "%s\n", line);
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
fprintf(stdout, "%s\n", line);
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
如果你必须使用a char *
,那么你仍然可以使用这个代码,但是你strdup()
的line[]
数组一旦填满了一行的输入值.free
一旦你完成它,你必须这个重复的字符串,否则你会得到内存泄漏:
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
char *dynamicLine = NULL;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)