从 stdin 读取行直到 EOF 并在测试第一个字符后打印文本

Read line from stdin until EOF and print the text after test for first character

我想交互(我想)从标准输入读取一行直到 EOF 但是如果行的第一个字符是 '+' 我想在每一行之后打印然后打印 "OK" 否则打印 "NOT OK"。我尝试了这段代码,但是即使我输入的行的第一个字符等于 '+'.

,它也会打印 "NOT OK"
int main()
{
    #define BUF_SIZE 1024
    char buffer[BUF_SIZE];
    size_t contentSize = 1;
    /* Preallocate space.  We could just allocate one char here,
    but that wouldn't be efficient. */
    char *content = malloc(sizeof(char) * BUF_SIZE);
    if(content == NULL)
    {
        perror("Failed to allocate content");
        exit(1);
    }
    content[0] = '[=10=]'; // make null-terminated
    while(fgets(buffer, BUF_SIZE, stdin))
    {
        char *old = content;
        contentSize += strlen(buffer);
        content = realloc(content, contentSize);
        if(content == NULL)
        {
            perror("Failed to reallocate content");
            free(old);
            exit(2);
        }
        strcat(content, buffer);
        if (content[0]== '+')  {
            printf("OK\n");
        } else {
            printf("NOT OK\n");
        }
    }

    if(ferror(stdin))
    {
        free(content);
        perror("Error reading from stdin.");
        exit(3);
    }
}

您正在将缓冲区连接到内容

strcat(content, buffer);

所以对于第一个输入,假设 "abc" content 将是 abc 并且它会打印 NOT OK 。 对于第二个输入,假设“+xyz”content 将是 abc+xyz 因此 content[0] 的值将始终是 "a" 因此它总是打印 NOT OK.

类似地,如果您的第一个输入是“+abc”,那么对于所有输入,它将始终打印 OK。

使用 strcpy 代替 strcat

strcpy(content, buffer);

要通过 fgets() 读取 ,最好将其作为独立函数处理

以下建议的代码与 OP 的类似。一个关键的区别是测试 fgets(buffer) 是否读取 '\n'.

#include <math.h>
#include <stdio.h>
#define BUF_SIZE 10

char *readline_mardon(void) {
  char buffer[BUF_SIZE];
  size_t contentSize = 1;
  char *content = malloc(contentSize);
  if (content == NULL) {
    perror("Failed to allocate content");
    exit(1);
  }
  content[0] = '[=10=]'; // make null-terminated
  while (fgets(buffer, sizeof buffer, stdin)) {
    size_t buffer_length = strlen(buffer);

    // more idiomatic code
    // Assign `content` after successful allocation detected
    size_t contentSize_new = contentSize + buffer_length;
    printf("%zu <%s>\n", buffer_length, buffer);
    char *content_new = realloc(content, contentSize_new);
    if (content_new == NULL) {
      perror("Failed to reallocate content");
      free(content);
      exit(2);
    }

    // memcpy faster than strcat as the end of the first part is known
    memcpy(content_new + contentSize - 1, buffer, buffer_length + 1);

    content = content_new;
    contentSize = contentSize_new;

    // look for \n
    if (buffer_length > 0 && buffer[buffer_length - 1] == '\n') {
      break;
    }
  }
  return content;
}

用法

char *s;
while((s = readline_mardon()) != NULL) {
  if (s[0]== '+')  {
    printf("OK\n");
  } else {
    printf("NOT OK\n");
  }
  free(s);
}

如果 未读取任何内容 或发生输入错误,则可以 return NULL 添加代码。