2010-10-12 15 views
21

मैंने टर्मिनल विंडो से लाइन पढ़ने के लिए निम्न कोड लिखा है, समस्या यह है कि कोड अनंत लूप में फंस जाता है। रेखा/वाक्य अपरिभाषित लंबाई का है, इसलिए मैं इसे बफर में भागों में पढ़ने की योजना बना रहा हूं, फिर इसे दूसरी स्ट्रिंग में जोड़ता हूं जिसे तदनुसार realloc के माध्यम से बढ़ाया जा सकता है। कृपया कोई मेरी गलती को देख सकता है या इसे प्राप्त करने का एक बेहतर तरीका सुझा सकता है?fgets() के साथ stdin से कैसे पढ़ा जाए?

#include <stdio.h> 
#include <string.h> 

#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; 
} 
+0

बहुत अच्छा लगता है, जब आप लूप को समाप्त करना चाहते हैं? जैसा कि अब है, आप इसे विंडोज़ पर ctrl + d पर * nix या ctrl + z पर मारकर समाप्त कर सकते हैं। – nos

+1

मुझे कोड के साथ स्पष्ट रूप से कुछ भी गलत नहीं दिख रहा है - जब आप कहते हैं "एक अनंत लूप में फंस गया", तो आपका क्या मतलब है? –

+0

मेरी क्रिस्टल बॉल मुझे बताती है कि पॉल आर ने समस्या को खारिज कर दिया है। समाधान लूप के अंदर 'printf' डालना है। – pmg

उत्तर

14
यहाँ

एक संयोजन समाधान:

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); 
4

आपको पता है कि fgets क्या लौटता है इसका गलत विचार है। इस पर एक नज़र डालें: http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

यह एक ईओएफ चरित्र पाता है जब यह शून्य हो जाता है। ऊपर दिए गए प्रोग्राम को चलाने और CTRL + D दबाएं (या जो भी संयोजन आपके ईओएफ चरित्र है), और लूप सफलतापूर्वक बाहर निकल जाएगा।

आप इनपुट के अंत का पता कैसे लगा सकते हैं? नई पंक्ति? डॉट (आपने वाक्य xD कहा)?

+0

इनपुट का अंत एक नई लाइन होना चाहिए – robdavies35

+0

न्यूलाइन के लिए अपने बफर को स्कैन करें, फिर :) – slezica

1

यह मानते हुए कि आप केवल, तो LINE_MAX, जो <limits.h> में परिभाषित किया गया है का उपयोग एक ही पंक्ति में पढ़ना चाहते हैं:

#include <stdio.h> 
... 
char line[LINE_MAX]; 
... 
if (fgets(line, LINE_MAX, stdin) != NULL) { 
... 
} 
... 
+3

LINE_MAX C89 या C99 नहीं है, इसका एकमात्र कंपाइलर विशिष्ट – user411313

+1

मजेदार है कि आप 'LINE_MAX' का उपयोग करके कोड दिखाएं, जिसमें' limit.h' –

0

आप श्रेणीबद्ध करना चाहते हैं इनपुट, फिर printf("%s\n", buffer);strcat(big_buffer, buffer); के साथ प्रतिस्थापित करें। शुरुआत में बड़े बफर को भी बनाएं और आरंभ करें: char *big_buffer = new char[BIG_BUFFERSIZE];big_buffer[0] = '\0';। आपको वर्तमान बफर लंबाई की पुष्टि करके एक बफर ओवररन को भी रोकना चाहिए और नई बफर लंबाई सीमा से अधिक नहीं है: if ((strlen(big_buffer) + strlen(buffer)) < BIG_BUFFERSIZE)। संशोधित कार्यक्रम इस तरह दिखेगा:

#include <stdio.h> 
#include <string.h> 

#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; 
} 
+0

शामिल है 'नया' सी ++ है लेकिन सवाल सी –

1

यदि रेखा खाली है (कोड सुधार रहा है) लूप से बाहर निकलता है।

#include <stdio.h> 
#include <string.h> 

// 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; 
} 

एंटर दबाए जाने पर बाहर निकलें।

#include <stdio.h> 
#include <stdbool.h> 
#include <string.h> 
#include <assert.h> 

#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; 
} 

एक स्ट्रिंग में कॉन्सटेनेशन और डाइनैमिक आवंटन (लिंक्ड लिस्ट)।

/* Autor : Tiago Portela 
    Email : [email protected] 
    Sobre : Compilado com TDM-GCC 5.10 64-bit e LCC-Win32 64-bit; 
    Obs : Apenas tentando aprender algoritimos, sozinho, por hobby. */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <string.h> 
#include <assert.h> 

#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; 
} 
+0

के बारे में है, क्या मैं गलत हूं, या लूप केवल तभी निकला है जब खाली लाइन बस बफरफायर सीमा के बाद आती है? –

+0

@ एलन बेकर मैंने इस घटना में लूप से वास्तव में कोड (मुझे लगता है) में सुधार किया है, लेकिन अब केवल तभी छोड़ दिया जाता है जब रेखा खाली हो (कुछ भी टाइप किए बिना एंटर दबाएं), मैंने टीडीएम-जीसीसी और एलसीसी के साथ परीक्षण किया। – sapitando

+0

वास्तव में (ए) कोड की दीवार पोस्ट करने में बहुत अधिक बिंदु नहीं है (बी) (6) के बारे में कोई स्पष्टीकरण नहीं है कि (6) पहले से ही अच्छे उत्तर हैं। –

संबंधित मुद्दे