通过scanf输入字符串

时间:2009-04-23 14:58:00

标签: c

我想问一下是否可以通过scanf在字符串中输入空白, 我正在使用这个[^ \ n]输入所有排除换行符的内容。它是否正确?但是它创建了很多问题,因为它似乎存储在输入缓冲区中。输入字符串的最佳方法是什么。 fgets正在制造很多问题,

        while(strcmp(buf,"quit"))
               {    
            scanf("%*[^\n]",buf);
            n=send(connected,buf,strlen(buf),0);
            if(n<0)
            {
            perror("send");
            printf("error sending");
            exit(1);
            }
            //printf("server has send\n");
            n=recv(connected,buf,100,0);
            if(n<0)
            {
            perror("recv");
            printf("error recieving");
            exit(1);
            }
            //printf("waiting to recieve something\n");
            buf[n]='\0';
            printf("client:%s\n",buf);
        }

这是创造无限循环,同样的事情一次又一次地重复。

5 个答案:

答案 0 :(得分:1)

读取输入线的更好方法是

char line[128]; /* Or whatever. */

while(fgets(stdin, line, sizeof line) != NULL)
{
  /* Filter out whitespace before checking tokens. */
}

答案 1 :(得分:0)

如果你遇到的所有问题都是空行,请使用strcmp("\n", buffer) == 0

您发布的正则表达式效果不佳,因为C会将'\n'中的"%*[^\n]"字符转换为字面换行符。为了让它更好地工作,你需要改变斜线:"%*[^ \ \n]"

然而,看起来麻烦也在于阅读,我建议你使用更好的功能。

我之前使用过以下代码从文件中读取任意大小的连续行。

尽管如此:

  1. 完成后,返回的缓冲区需要free() d
  2. 代码每次迭代都会浪费几个字节,但除非BUFFER_SIZE与行的长度相比非常小,否则这并不是很明显。
  3. 但是,代码可以保证从FILE *读取一个完整的行,它将以'\ n'结尾。

    /*
     * Initial size of the read buffer
     */
    #define DEFAULT_BUFFER 1024
    
    /*
     * Standard boolean type definition
     */
    typedef enum{ false = 0, true = 1 }bool;
    
    /*
     * Flags errors in pointer returning functions
     */
    bool has_err = false;
    
    /*
     * Reads the next line of text from file and returns it.
     * The line must be free()d afterwards.
     *
     * This function will segfault on binary data.
     */
    char *readLine(FILE *file){
        char *buffer   = NULL;
        char *tmp_buf  = NULL;
        bool line_read = false;
        int  iteration = 0;
        int  offset    = 0;
    
        if(file == NULL){
            fprintf(stderr, "readLine: NULL file pointer passed!\n");
            has_err = true;
    
            return NULL;
        }
    
        while(!line_read){
            if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
                fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
                if(buffer != NULL)
                    free(buffer);
                has_err = true;
    
                return NULL;
            }
    
            if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
                free(tmp_buf);
    
                break;
            }
    
            if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
                line_read = true;
    
            offset = DEFAULT_BUFFER * (iteration + 1);
    
            if((buffer = realloc(buffer, offset)) == NULL){
                fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
                free(tmp_buf);
                has_err = true;
    
                return NULL;
            }
    
            offset = DEFAULT_BUFFER * iteration - iteration;
    
            if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
                fprintf(stderr, "readLine: Cannot copy to buffer\n");
                free(tmp_buf);
                if(buffer != NULL)
                    free(buffer);
                has_err = true;
    
                return NULL;
            }
    
            free(tmp_buf);
            iteration++;
        }
    
        return buffer;
    }
    

答案 2 :(得分:0)

如果您的开发环境支持,您也可以使用getline()

答案 3 :(得分:0)

scanf("%*[^\n]",buf);存在两个问题:

  1. 说明符中的星号会导致值被扫描,但不会被存储。
  2. 扫描到下一个换行符,但不消耗该字符。这意味着第一个之后的每个电话都不会读。

答案 4 :(得分:0)

我认为您正在寻找的scanf是:

scanf(“%[^ \ n]%* c”,buf);

%[^ \ n]获取您的字符串,%* c忽略换行符。

但是,如果你谷歌“如何不读取c中的字符串”,这就是你得到的字面意思

非阻塞输入完全是另一回事。你可能会谷歌“cbreak模式”。但是,这是一个unix-y终端的东西,如果你在Windows上,那可能没有意义。 X / Gtk / Qt将有其他方式来做这类事情。