在 C 中逐行读取文件(不使用 fgets)
read file line by line in C(without using fgets)
我有一个包含 3 行的文件,我想读取这个文件并将每一行保存为一个单独的字符串。
这是我尝试做的,它确实保存了第一行,但它通过保存第一行和第二行来覆盖它'而且我无法理解如何将每一行保存为单独的字符串,并且我也收到错误->
* stack smashing detected *: /home/ubuntu/workspace/ex12.c.o terminated
Aborted
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
#include <unistd.h>
extern int errno;
int main( int argc, char *argv[] ) {
char *path1;
char firstline[80];
char secondline[80];
char thirdline[80];
printf("Program name %s\n", argv[0]);
if( argc == 2 ) {
printf("The path of the config file that you supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
else {
printf("One argument expected.\n");
}
int fd1 = open(argv[1], O_RDONLY | O_CREAT);
if (fd1 ==-1)
{
// print which type of error have in a code
printf("Error Number % d\n", errno);
// print program detail "Success or failure"
perror("Program");
exit(EXIT_FAILURE);
}
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
//printf("end of line");
printf("%s",firstline);
}
}
}
int close(int fd1);
return 0;
}
注意:我不想使用 fopen、fgets、sscanf 或 getline。
任何帮助将不胜感激
printf
打印直到看到 NULL 终止字符。您的 printf 遍历未分配的内存区域,因为您没有在字符串末尾插入 NULL(value 0)。
另外,您忘记将 i 重新初始化为 0。
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
firstline[i] = 0;
i = 0;
//printf("end of line");
printf("%s",firstline);
}
}
您收到错误的原因很可能是因为您从未将 i
重置回 0,因此您一直在 firstline
中读取超过 80 个字符
至于将每一行保存到它自己的字符串中,您只需要使用其他变量,而不是一直使用 firstline
。
有几种方法可以做到这一点:
当您检测到行尾时退出循环(使用 break
),并开始另一个循环,您将在其中将字符放入 secondline
。对第三个做同样的事情。
如果你已经了解了一些关于指针的知识,你可以保留一个循环,但是使用一个额外的变量,比如 char *currentLine
来保存你想要读入的数组的地址到。每次检测到行尾时更改地址:currentLine = secondline
.
还请记住在您阅读的每一行末尾放置“\0”,否则当您尝试将阅读的内容打印到屏幕上时,您的程序可能会打印出乱码。
以下建议代码:
- 干净地编译
- 执行所需的功能
- 正确检查并处理错误
- 给出 'magic' 个数字 (3, 80) 有意义的名字
现在,建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#define MAX_LINES 3
#define MAX_LINE_LEN 80
int main( int argc, char *argv[] )
{
char Lines[ MAX_LINES ][ MAX_LINE_LEN ] = { '[=10=]' };
if( argc != 2 )
{
fprintf( stderr, "USAGE: %s <configFileName>\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of command line arguments
int fd1 = open(argv[1], O_RDONLY );
if (fd1 ==-1)
{
perror( "open failed" );
exit(EXIT_FAILURE);
}
// implied else, open successful
char c;
for( int i = 0; i < MAX_LINES; i++ )
{
for( int j=0; j< MAX_LINE_LEN; j++ )
{
ssize_t bytecount = read(fd1, &c, 1 );
if( bytecount < 0 )
{
perror( "read failed" );
close( fd1 );
exit( EXIT_FAILURE );
}
// implied else, read successful
Lines[ i ][ j ] = c;
if( c == '\n' )
{
break;
}
}
}
for( int i = 0; i< MAX_LINES; i++ )
{
printf( "%s\n", Lines[i] );
}
close( fd1 );
return 0;
}
注意:此代码假定每行少于 80 个字符
运行 针对其自身源文件的建议代码导致:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
这是一个示例,用于演示示例中第一个循环的制动器:
#define MAXLENGTH 80
...
char firstline[MAXLENGTH + 1] = {0};
char secondline[MAXLENGTH + 1] = {0};
char thirdline[MAXLENGTH + 1] = {0};
....
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
firstline[i++]=c;
if(c=='\n')
{
break; /* break from first loop */
}
}
/* add a '[=10=]' to the end of the string! */
firstline[i] = '[=10=]';
//printf("end of line");
printf("%s",firstline);
i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
secondline[i++]=c;
if(c=='\n')
{
break; /* break from second loop */
}
}
/* add a '[=10=]' to the end of the string! */
secondline[i] = '[=10=]';
printf("%s",secondline);
i = 0;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
thirdline[i++]=c;
if(c=='\n')
{
break; /* break from third loop */
}
}
/* add a '[=10=]' to the end of the string! */
thirdline[i] = '[=10=]';
//printf("end of line");
printf("%s",thirdline);
}
...
我有一个包含 3 行的文件,我想读取这个文件并将每一行保存为一个单独的字符串。 这是我尝试做的,它确实保存了第一行,但它通过保存第一行和第二行来覆盖它'而且我无法理解如何将每一行保存为单独的字符串,并且我也收到错误->
* stack smashing detected *: /home/ubuntu/workspace/ex12.c.o terminated Aborted
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
#include <unistd.h>
extern int errno;
int main( int argc, char *argv[] ) {
char *path1;
char firstline[80];
char secondline[80];
char thirdline[80];
printf("Program name %s\n", argv[0]);
if( argc == 2 ) {
printf("The path of the config file that you supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
else {
printf("One argument expected.\n");
}
int fd1 = open(argv[1], O_RDONLY | O_CREAT);
if (fd1 ==-1)
{
// print which type of error have in a code
printf("Error Number % d\n", errno);
// print program detail "Success or failure"
perror("Program");
exit(EXIT_FAILURE);
}
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
//printf("end of line");
printf("%s",firstline);
}
}
}
int close(int fd1);
return 0;
}
注意:我不想使用 fopen、fgets、sscanf 或 getline。 任何帮助将不胜感激
printf
打印直到看到 NULL 终止字符。您的 printf 遍历未分配的内存区域,因为您没有在字符串末尾插入 NULL(value 0)。
另外,您忘记将 i 重新初始化为 0。
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
firstline[i] = 0;
i = 0;
//printf("end of line");
printf("%s",firstline);
}
}
您收到错误的原因很可能是因为您从未将 i
重置回 0,因此您一直在 firstline
至于将每一行保存到它自己的字符串中,您只需要使用其他变量,而不是一直使用 firstline
。
有几种方法可以做到这一点:
当您检测到行尾时退出循环(使用
break
),并开始另一个循环,您将在其中将字符放入secondline
。对第三个做同样的事情。如果你已经了解了一些关于指针的知识,你可以保留一个循环,但是使用一个额外的变量,比如
char *currentLine
来保存你想要读入的数组的地址到。每次检测到行尾时更改地址:currentLine = secondline
.
还请记住在您阅读的每一行末尾放置“\0”,否则当您尝试将阅读的内容打印到屏幕上时,您的程序可能会打印出乱码。
以下建议代码:
- 干净地编译
- 执行所需的功能
- 正确检查并处理错误
- 给出 'magic' 个数字 (3, 80) 有意义的名字
现在,建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#define MAX_LINES 3
#define MAX_LINE_LEN 80
int main( int argc, char *argv[] )
{
char Lines[ MAX_LINES ][ MAX_LINE_LEN ] = { '[=10=]' };
if( argc != 2 )
{
fprintf( stderr, "USAGE: %s <configFileName>\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of command line arguments
int fd1 = open(argv[1], O_RDONLY );
if (fd1 ==-1)
{
perror( "open failed" );
exit(EXIT_FAILURE);
}
// implied else, open successful
char c;
for( int i = 0; i < MAX_LINES; i++ )
{
for( int j=0; j< MAX_LINE_LEN; j++ )
{
ssize_t bytecount = read(fd1, &c, 1 );
if( bytecount < 0 )
{
perror( "read failed" );
close( fd1 );
exit( EXIT_FAILURE );
}
// implied else, read successful
Lines[ i ][ j ] = c;
if( c == '\n' )
{
break;
}
}
}
for( int i = 0; i< MAX_LINES; i++ )
{
printf( "%s\n", Lines[i] );
}
close( fd1 );
return 0;
}
注意:此代码假定每行少于 80 个字符
运行 针对其自身源文件的建议代码导致:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
这是一个示例,用于演示示例中第一个循环的制动器:
#define MAXLENGTH 80
...
char firstline[MAXLENGTH + 1] = {0};
char secondline[MAXLENGTH + 1] = {0};
char thirdline[MAXLENGTH + 1] = {0};
....
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
firstline[i++]=c;
if(c=='\n')
{
break; /* break from first loop */
}
}
/* add a '[=10=]' to the end of the string! */
firstline[i] = '[=10=]';
//printf("end of line");
printf("%s",firstline);
i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
secondline[i++]=c;
if(c=='\n')
{
break; /* break from second loop */
}
}
/* add a '[=10=]' to the end of the string! */
secondline[i] = '[=10=]';
printf("%s",secondline);
i = 0;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
thirdline[i++]=c;
if(c=='\n')
{
break; /* break from third loop */
}
}
/* add a '[=10=]' to the end of the string! */
thirdline[i] = '[=10=]';
//printf("end of line");
printf("%s",thirdline);
}
...