如何用fgets()读取stdin?

我写了下面的代码来从终端窗口读取一行,问题是代码卡在无限循环中。 行/句子的长度是未定义的,因此我计划将其部分读入缓冲区,然后将其连接到另一个字符串,该字符串可以通过realloc相应的扩展。 有人可以发现我的错误或建议更好的方法来实现这个目标吗?

 #include  #include  #define BUFFERSIZE 10 int main (int argc, char *argv[]) { char buffer[BUFFERSIZE]; printf("Enter a message: \n"); while(fgets(buffer, BUFFERSIZE , stdin) != NULL) { printf("%s\n", buffer); } return 0; } 

这里是一个连接解决方​​案:

 #include  #include  #include  #define BUFFERSIZE 10 int main() { char *text = calloc(1,1), buffer[BUFFERSIZE]; printf("Enter a message: \n"); while( fgets(buffer, BUFFERSIZE , stdin) ) /* break with ^D or ^Z */ { text = realloc( text, strlen(text)+1+strlen(buffer) ); if( !text ) ... /* error handling */ strcat( text, buffer ); /* note a '\n' is appended here everytime */ printf("%s\n", buffer); } printf("\ntext:\n%s",text); return 0; } 

你对fgets的回报有错误的想法。 看看这个: http : //www.cplusplus.com/reference/clibrary/cstdio/fgets/

它在找到EOF字符时返回null。 尝试运行上面的程序并按CTRL + D(或任何组合是你的EOF字符),循环将成功退出。

您想如何检测输入结束? 新队? Dot(你说的句子xD)?

假设您只想读取一行,则使用LINE_MAX ,它在定义:

 #include  ... char line[LINE_MAX]; ... if (fgets(line, LINE_MAX, stdin) != NULL) { ... } ... 

如果该行为空,则退出循环(改进代码)。

 #include  #include  // The value BUFFERSIZE can be changed to customer's taste . Changes the // size of the base array (string buffer ) #define BUFFERSIZE 10 int main(void) { char buffer[BUFFERSIZE]; char cChar; printf("Enter a message: \n"); while(*(fgets(buffer, BUFFERSIZE, stdin)) != '\n') { // For concatenation // fgets reads and adds '\n' in the string , replace '\n' by '\0' to // remove the line break . /* if(buffer[strlen(buffer) - 1] == '\n') buffer[strlen(buffer) - 1] = '\0'; */ printf("%s", buffer); // Corrects the error mentioned by Alain BECKER. // Checks if the string buffer is full to check and prevent the // next character read by fgets is '\n' . if(strlen(buffer) == (BUFFERSIZE - 1) && (buffer[strlen(buffer) - 1] != '\n')) { // Prevents end of the line '\n' to be read in the first // character (Loop Exit) in the next loop. Reads // the next char in stdin buffer , if '\n' is read and removed, if // different is returned to stdin cChar = fgetc(stdin); if(cChar != '\n') ungetc(cChar, stdin); // To print correctly if '\n' is removed. else printf("\n"); } } return 0; } 

按Enter键时退出。

 #include  #include  #include  #include  #define BUFFERSIZE 16 int main(void) { char buffer[BUFFERSIZE]; printf("Enter a message: \n"); while(true) { assert(fgets(buffer, BUFFERSIZE, stdin) != NULL); // Verifies that the previous character to the last character in the // buffer array is '\n' (The last character is '\0') if the // character is '\n' leaves loop. if(buffer[strlen(buffer) - 1] == '\n') { // fgets reads and adds '\n' in the string, replace '\n' by '\0' to // remove the line break . buffer[strlen(buffer) - 1] = '\0'; printf("%s", buffer); break; } printf("%s", buffer); } return 0; } 

连接和dinamic分配(链表)到单个字符串。

 /* Autor : Tiago Portela Email : sapitando@gmail.com Sobre : Compilado com TDM-GCC 5.10 64-bit e LCC-Win32 64-bit; Obs : Apenas tentando aprender algoritimos, sozinho, por hobby. */ #include  #include  #include  #include  #include  #define BUFFERSIZE 8 typedef struct _Node { char *lpBuffer; struct _Node *LpProxNode; } Node_t, *LpNode_t; int main(void) { char acBuffer[BUFFERSIZE] = {0}; LpNode_t lpNode = (LpNode_t)malloc(sizeof(Node_t)); assert(lpNode!=NULL); LpNode_t lpHeadNode = lpNode; char* lpBuffer = (char*)calloc(1,sizeof(char)); assert(lpBuffer!=NULL); char cChar; printf("Enter a message: \n"); // Exit when Enter is pressed /* while(true) { assert(fgets(acBuffer, BUFFERSIZE, stdin)!=NULL); lpNode->lpBuffer = (char*)malloc((strlen(acBuffer) + 1) * sizeof(char)); assert(lpNode->lpBuffer!=NULL); strcpy(lpNode->lpBuffer, acBuffer); if(lpNode->lpBuffer[strlen(acBuffer) - 1] == '\n') { lpNode->lpBuffer[strlen(acBuffer) - 1] = '\0'; lpNode->LpProxNode = NULL; break; } lpNode->LpProxNode = (LpNode_t)malloc(sizeof(Node_t)); lpNode = lpNode->LpProxNode; assert(lpNode!=NULL); }*/ // Exits the loop if the line is empty(Improving code). while(true) { assert(fgets(acBuffer, BUFFERSIZE, stdin)!=NULL); lpNode->lpBuffer = (char*)malloc((strlen(acBuffer) + 1) * sizeof(char)); assert(lpNode->lpBuffer!=NULL); strcpy(lpNode->lpBuffer, acBuffer); if(acBuffer[strlen(acBuffer) - 1] == '\n') lpNode->lpBuffer[strlen(acBuffer) - 1] = '\0'; if(strlen(acBuffer) == (BUFFERSIZE - 1) && (acBuffer[strlen(acBuffer) - 1] != '\n')) { cChar = fgetc(stdin); if(cChar != '\n') ungetc(cChar, stdin); } if(acBuffer[0] == '\n') { lpNode->LpProxNode = NULL; break; } lpNode->LpProxNode = (LpNode_t)malloc(sizeof(Node_t)); lpNode = lpNode->LpProxNode; assert(lpNode!=NULL); } printf("\nPseudo String :\n"); lpNode = lpHeadNode; while(lpNode != NULL) { printf("%s", lpNode->lpBuffer); lpNode = lpNode->LpProxNode; } printf("\n\nMemory blocks:\n"); lpNode = lpHeadNode; while(lpNode != NULL) { printf("Block \"%7s\" size = %lu\n", lpNode->lpBuffer, (long unsigned)(strlen(lpNode->lpBuffer) + 1)); lpNode = lpNode->LpProxNode; } printf("\nConcatenated string:\n"); lpNode = lpHeadNode; while(lpNode != NULL) { lpBuffer = (char*)realloc(lpBuffer, (strlen(lpBuffer) + strlen(lpNode->lpBuffer)) + 1); strcat(lpBuffer, lpNode->lpBuffer); lpNode = lpNode->LpProxNode; } printf("%s", lpBuffer); printf("\n\n"); // Deallocate memory lpNode = lpHeadNode; while(lpNode != NULL) { lpHeadNode = lpNode->LpProxNode; free(lpNode->lpBuffer); free(lpNode); lpNode = lpHeadNode; } lpBuffer = (char*)realloc(lpBuffer, 0); lpBuffer = NULL; if((lpNode == NULL) && (lpBuffer == NULL)) { printf("Deallocate memory = %s", (char*)lpNode); } printf("\n\n"); return 0; } 

如果要连接输入,则替换printf("%s\n", buffer);strcat(big_buffer, buffer); 。 同时在开头创建并初始化大缓冲区: char *big_buffer = new char[BIG_BUFFERSIZE]; big_buffer[0] = '\0'; 。 您还应该通过validation当前缓冲区长度加上新缓冲区长度不超过限制来阻止缓冲区溢出: if ((strlen(big_buffer) + strlen(buffer)) < BIG_BUFFERSIZE) 。 修改后的程序如下所示:

 #include  #include  #define BUFFERSIZE 10 #define BIG_BUFFERSIZE 1024 int main (int argc, char *argv[]) { char buffer[BUFFERSIZE]; char *big_buffer = new char[BIG_BUFFERSIZE]; big_buffer[0] = '\0'; printf("Enter a message: \n"); while(fgets(buffer, BUFFERSIZE , stdin) != NULL) { if ((strlen(big_buffer) + strlen(buffer)) < BIG_BUFFERSIZE) { strcat(big_buffer, buffer); } } return 0; }