C语言 使用 fgets() 读取多行。如何转到下一行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19405254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using fgets() to read multiple lines. How to go to the Next line?
提问by Kevin Ko
So I am opening a file that contains cards data for a card game I am designing for my assignment, basically each line contains 104 characters and each line is equal to a deck of card.
所以我正在打开一个文件,其中包含我正在为我的任务设计的纸牌游戏的纸牌数据,基本上每行包含 104 个字符,每行等于一副纸牌。
I'm using a char ****because of
我正在使用一个char ****因为
- number of decks
- num of players (4)
- num of cards (13)
- card is represented like
9H,3Dmeans nine of hearts and three of diamonds, so it uses 2 characters.
- 甲板数量
- 玩家人数 (4)
- 卡数 (13)
- card 表示为
9H,3D表示九颗心和三颗菱形,因此它使用 2 个字符。
I want to use fgets()to read multiple lines but I'm not sure if this works...
我想用来fgets()阅读多行,但我不确定这是否有效......
forloop is just the way how the deckfile is set, I just want to know if the fgetswill go to the next line when it hits \n...
for循环只是甲板文件的设置方式,我只是想知道它是否fgets会在命中时转到下一行\n......
di->cards = (char ****)malloc(sizeof(char***) * di->numDecks);
for (i = 0; i < di->numDecks; i++) {
di->cards[i] = (char ***)malloc(sizeof(char**) * 4);
for (j = 0; j < 4, j++) {
di->cards[i][j] = (char **)malloc(sizeof(char*) * 13);
for (k = 0, k < 13, k++) {
di->cards[i][j][k] = (char *)malloc(sizeof(char) * 3);
}
}
}
for (i = 0; i < di->numDecks, i++) {
for (j = 0; j < 13, j++) {
for (k = 0; k < 4; k++) {
while ((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
}
}
}
回答by ryyker
fgets()is often called in a loop, such as this:
fgets()通常在循环中调用,例如:
FILE *fp;
char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
fp = fopen("C:\somedir\card.txt", "r");
while(fgets(buf, sizeof(buf), fp)) //where sizeof(buf) is the length of
//line you anticipate reading in.
{
//do something with buf here;
//The input of fgets will be NULL as soon
//as its input fp has been fully read, then exit the loop
}
fclose(fp);
Your statement while((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
has a couple of issues, one is the ;at the end. It will just loop on this one line, and not give you a chance to do anything with the line that is read before it reads the next one. Also, 3is probably not the length of line you want to read, is it? 3 is the buffer size that will hold your card data, but the lineyou read from the file will be longer.
你的陈述while((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
有几个问题,一个是;最后。它只会在这一行上循环,并且不会让您有机会在读取下一行之前对读取的行进行任何操作。另外,3可能不是您要阅读的行长,是吗?3 是保存卡数据的缓冲区大小,但从文件中读取的行会更长。
So, in addition to these points, consider the other ideas in the comments, and make changes as indicated.
因此,除了这些要点之外,请考虑评论中的其他想法,并按照指示进行更改。
[EDIT]modified to read a file with "AS3D4C...(52 cards)" 4 lines
It will fill in enough spaces for 4 decks of cards. You can use this to
see how to read in the data. strtok (used before) works only when there
are delimiters, which if you can, I would recommend using instead of
long strings. Hope this helps.
(Note, I used no [mc]alloc()'s in this example.
[编辑]修改为读取带有“AS3D4C...(52 张卡片)” 4 行的文件
它将为 4副卡片填充足够的空间。您可以使用它来
查看如何读入数据。strtok(以前使用过)仅在有
分隔符时才起作用,如果可以,我建议使用它而不是
长字符串。希望这可以帮助。
(注意,我在这个例子中没有使用 [mc]alloc() 。
#include <ansi_c.h>
#define FILENAME "C:\dev\play\cards.txt"
int main()
{
int i, j;
FILE *fp;
char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
char *cardTok;
char cards[208][3]; //4 players, 4 decks, each card is 3 bytes (eg. [A|S|9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQhKD
6C9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
2D9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
3S9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4S
], they all need a null termination)
memset(cards, 0, 208*3);
fp = fopen(FILENAME, "r");
j = 0;
while(fgets(buf, sizeof(buf), fp)) //where buf len is initialized at 260
//and well over the anticipated 104/line, including \n etc.
{ //note, fgets() will read up to n-1 characters and place a #include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
at the end
//but will stop reading sooner if it sees end of line.
for(i=0;i<52;i++) //i is card number
{
cards[i+j][0] = buf[2*i+0];
cards[i+j][1] = buf[2*i+1];
cards[i+j][2] = 0;
}
j+=52;
}
fclose(fp);
}
My text file looked like this:
我的文本文件如下所示:
char line[100]; // here you can use char *line=malloc(100);
fgets(line,sizeof line,file_stream);
printf("%s\n",line);
回答by Gangadhar
char lines[20][100]; // here you can use char **lines=malloc(100);
i=0;
//if you use **lines allocate size for all lines with the loop or else you can allocate size inside loop and then read.
while((fgets(lines[i],SIZE_ALLOCATED_FOR_LINE,file_stream)!=NULL) && (i<20))
{
printf("%s\n",line[i++]);
}
fgets()reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOFor a newline.
fgets()从流中读取至多小于 size 的一个字符,并将它们存储到 s 指向的缓冲区中。阅读在 aEOF或 a 之后停止newline。
be careful with this : If a newlineis read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
请注意:如果newline读取了 a ,则将其存储到缓冲区中。终止空字节 ('\0') 存储在缓冲区中的最后一个字符之后。
When you want to compare line , before you need to remove \nbefore null byte.
当你想比较 line 时,在你需要删除\n之前的空字节之前。
If you want to read single line.
如果你想阅读单行。
char *fgets( char *str, int count, FILE *stream );
char *fgets( char *restrict str, int count, FILE *restrict stream );
if you want to read multiple lines
如果你想阅读多行
##代码##回答by Suvarna Pattayil
The documentationsays,
该文件说,
##代码##Reads at most
count - 1characters from the given file stream and stores them instr. The produced character string is always NULL-terminated. Parsing stops if end-of-file occurs or a newline characteris found, in which case str will contain that newline character.
从给定的文件流中读取至多
count - 1字符并将它们存储在str. 生成的字符串始终以 NULL 结尾。如果出现文件结束符或找到换行符,解析将停止,在这种情况下 str 将包含该换行符。
Also,
还,
The return value is NULLon failure.
返回值是NULL失败。
If the failure has been caused by EOFcondition, additionally sets the eof indicator (see feof()) on stdin. If the failure has been caused by some other error, sets the error indicator (see ferror()) on stdin.
如果失败是由EOF条件引起的,则在 stdin 上另外设置 eof 指示符(参见 feof())。如果失败是由某些其他错误引起的,请在 stdin 上设置错误指示符(请参阅 ferror())。
Also check for feofto ensure NULLwas obtained due to EOF
还要检查feof以确保NULL由于 EOF 而获得
回答by user3727944
If you want to take the fgets input and input all of it into an array of arrays or string array how could you do that. I have tried different things but get seg faults
如果您想获取 fgets 输入并将其全部输入到数组数组或字符串数组中,您该怎么做。我尝试了不同的东西,但遇到了段错误

