【问题标题】:c programming read input error checkingc编程读取输入错误检查
【发布时间】:2017-11-18 01:25:30
【问题描述】:

有没有办法让这种错误检查变得更好?还是我忘记了什么?我期待一个整数然后是字符串。我将建议添加到代码中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>

int main(void) {
    // your code goes here
    char line[150] = {0};
    int sscanf_counter = 0;
    int num = 0;
    char string[150] = {0};
    char dummy; 

    while(fgets(line, sizeof line, stdin))
    {
        printf("line is %s\n", line);
        sscanf_counter = sscanf(line, "%d %s %c", &num, string, &dummy);
        printf ("sscanf_counter: %d\n", sscanf_counter);
        if (sscanf_counter == 2 && isalpha(string[0])) 
        {
            printf ("Good value: %d\n", num);
            printf ("string: <%s>\n", string);
        }
        else 
        {
            printf ("BAD VALUE: %d \n", num);
            printf ("string: <%s>\n", string);
        }
        memset(line, 0, sizeof line);
    }

    printf("Does this print? \n");

    return 0;
}

我不想将 222 转换为字符串,所以我在我的代码中添加了一个简单的 isalpha() 检查。我想要一个实际数字作为我的第一个值和实际字母字符而不是数字转换为第二个值的字符串。

稍作调整的输出:

aaa aaa
line is aaa aaa

sscanf_counter: 0
BAD VALUE: 0
string: <>
111 222
line is 111 222

sscanf_counter: 2
BAD VALUE: 111
string: <222>
111 aaa
line is 111 aaa

sscanf_counter: 2
Good value: 111
string: <aaa>

【问题讨论】:

  • 为了获得更好的反馈,请发布所使用的真实输入、看到的输出和预期的输出。
  • @chux 我更新了我的代码。我在我的代码中添加了isalpha() check 的小调整。
  • noobprogrammer1987 isalpha(string[0]) 没有为string[0] 的大多数负值定义。高度可移植的代码使用isalpha((unsigned char) string[0])
  • @chux 它甚至不是“高度可移植的”,许多在最常用的签名字符平台上调试 CRT ;) 将直接 assert 用于负值。
  • @AnttiHaapala 你能详细说明你在说什么吗?

标签: c error-handling


【解决方案1】:

有没有办法让这种错误检查变得更好?

"%d" 未在溢出时指定。 strtol() 可以提供更强大的错误检查。

"%d %s" 不检测无关的额外输入。

要处理额外的输入并仍然使用sscanf(),请参见下文。如果sscanf_counter == 3,检测到额外的非空白输入。

char dummy;
sscanf_counter = sscanf(line, "%d %s %c", &num, string, &dummy);

测试if (sscanf_counter == ...) 应该发生在之前使用变量。

  printf ("sscanf_counter: %d\n", sscanf_counter);
  if (sscanf_counter >= 1) printf ("num: %d\n", num);
  if (sscanf_counter >= 2) printf ("string: %s\n", string);

提示:打印字符串时,请考虑使用可打印的句子来帮助检测前导/尾随空格问题。 (尽管"%s" 不会出现这些。)

// printf ("string: %s\n", string);
printf ("string: <%s>\n", string);

OT:不要编写幻数,而是使用能适应的代码

// memset(line, 0, 150);
memset(line, 0, sizeof line);

// while(fgets(line, 150, stdin) != NULL)
while (fgets(line, sizeof line, stdin))

【讨论】:

  • 谢谢。我假设将虚拟对象添加到 sscanf 的末尾只是为了告诉我是否有额外的输入?它还有其他作用吗?可打印的句子是什么意思?谢谢sizeof的提醒。括号大小是可选的吗?我第一次使用没有括号的 sizeof 并且没有任何问题时感到很惊讶。
  • 在while循环结束时不需要!= NULL吗?
  • @noobprogrammer1987 while (fgets(line, sizeof line, stdin))while (fgets(line, sizeof line, stdin) != NULL) 功能相同,根据您组的编码风格进行编码。
  • @noobprogrammer1987 sizeof object 代码与sizeof(object) 相同。带type,必须使用sizeof(type)
  • @noobprogrammer1987 是的,dummy 可以检测额外的输入。
猜你喜欢
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 2012-09-08
  • 2011-11-04
  • 1970-01-01
相关资源
最近更新 更多