如何使用sscanf获取姓名并以我希望的方式打印出来

如何使用sscanf获取姓名并以我希望的方式打印出来,c,ansi,main,scanf,fgetc,C,Ansi,Main,Scanf,Fgetc,我正在制作一个程序,该程序使用逗号分隔的用户名称。该程序允许用户在逗号之间放置任意多或任意小的空格。例如: 如果我输入类似的内容 Smith, John Smith , John 或 我想打印出来 John, Smith 问题是,尽管我的程序没有正确地处理上面的例子;如果输入类似于 Smith, John Smith , John 或 这是我的密码: #include <stdio.h> #include <string.h> #include <ctyp

我正在制作一个程序,该程序使用逗号分隔的用户名称。该程序允许用户在逗号之间放置任意多或任意小的空格。例如:

如果我输入类似的内容

Smith, John
Smith , John

我想打印出来

John, Smith
问题是,尽管我的程序没有正确地处理上面的例子;如果输入类似于

Smith, John
Smith , John

这是我的密码:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define LINESIZE 128

int get_last_first(FILE *fp);

int main (void)
{
    get_last_first(stdin);
}

/*takes names in the format [LASTNAME],[FIRSTNAME]*/
int get_last_first(FILE *fp)
{
    char first[LINESIZE];
    char last[LINESIZE];
    char line[LINESIZE];
    size_t i;

    while(1)
    {
        printf("Enter your last name followed by a comma and your first name\n");

        /*if we cant read a line from stdin*/
        if(!fgets(line, LINESIZE, fp)) 
        {
            clearerr(stdin);
            break;   /*stop the loop*/
        }

        /*goes through the line array and checks for non-alphabetic characters*/        
        for(i = 0; i < strlen(line); i++)
        {
            if(!isalpha(line[i]))
            {
                /*if it sees a space hyphen or comma, it continues the program*/
                if((isspace(line[i]) || line[i] == ',') || line[i] == '-' )
                {
                    continue;
                }
                else
                {
                    return -1;
                }
            }

        }

        if(sscanf(line, "%s , %s", last, first))
        {
            printf("%s, %s", first, last);
            return 1;
        }

        return 0;   

    }
}
#包括
#包括
#包括
#定义线宽128
int get_last_first(文件*fp);
内部主(空)
{
先获得最后一个(标准输入);
}
/*采用[LASTNAME]、[FIRSTNAME]格式的名称*/
int get_last_first(文件*fp)
{
字符优先[行大小];
最后一个字符[行大小];
字符行[行大小];
尺寸i;
而(1)
{
printf(“输入您的姓氏,后跟逗号和您的名字\n”);
/*如果我们读不到标准文本中的一行*/
如果(!fgets(线条、线条尺寸、fp))
{
clearerr(标准偏差);
中断;/*停止循环*/
}
/*遍历行数组并检查非字母字符*/
对于(i=0;i

是因为我没有正确使用sscanf吗?

sscanf()
不进行模式匹配;逗号是完全有效的非空白字符串组件,因此将被
%s
规范所取代。您可以使用类似于
%[^\t,]
的方法来匹配一系列字符,最多可匹配一个空格或逗号。

基本问题在“s”中概述-是的,您误用了
sscanf()

代码中还有其他问题

  • 不要在循环测试中使用
    strlen()
    ;它每次都会被调用,并产生相同的答案(除非您在运行时对字符串进行了黑客攻击)。在循环之前调用它一次,并使用保存的值
  • 从风格上讲,在以下条件中有不必要的括号和空格(并且缺少必要的空格):

    if((isspace(line[i]) || line[i] == ',') || line[i] == '-' )
    
    if (isspace(line[i]) || line[i] == ',' || line[i] == '-')
    
    关键字后面应该有一个空格(参见标准)。没有必要用额外的括号破坏三向条件的对称性;最后一个右括号前不需要空格。(或者,如果您坚持这样做,那么在条件的左括号后需要一个平衡的空格。但请不要坚持。)

  • 您需要测试
    sscanf()
    是否成功转换了两个值;您只需检查它是否未转换0个值。它可能返回1;它可能返回EOF(以及0或2)

  • 您的“无限循环”被一个
    中断
    中断,但随后该函数不返回值
  • 您的
    main()
    程序忽略函数返回的值-因此您根本不需要输入返回值
  • 从风格上讲,尽管C99标准允许您省略
    main()
    结尾处的
    return
    ,但我更喜欢在那里看到它。(您没有犯过让
    main()
    return
    void
    ;谢谢。)
  • 您可能已经注意到,在格式化问题时,我删除了一些嵌入在注释中的错误代码。不要把死板的代码放在周围,也不要这样炫耀
  • 在风格上,我在
    #include
    之间加了空格。再一次,看看C标准,注意它们是如何编写的:
    #include
    ,你也是这样做的

标记为“风格上”的注释是建议-编译器基本上不注意空格或缺少空格。尽管如此,C标准显示了所有在
#中带有空格的示例,包括
行和关键字后面的空格,例如
for
if
,Kernighan和Ritchie对C的原始描述也是如此,因此您可以遵循一个坚实的先例。通常,如果您遵循标准约定,其他人会发现您的代码更容易阅读。大括号的位置更具争议性——但如果你遵循K&R(尽管我更喜欢这种样式),你不会错得太多。

严格来说,没有必要在关键字后面或#include和#include之间使用空格。我的意思是,我知道你的意思是好的,教好代码和东西的实践。。。我认为它是有效的,但我认为你应该明确指出,该标准并不强制执行,即使人们应该这样做。如果你不介意,你能告诉我如何在这种情况下正确使用它吗?我已经有一段时间没有使用正则表达式了,所以我有点生疏了。这不是正则表达式,是问题所在。:)<代码>%s
读取非空白序列
%[xyz]
读取字符序列
x
y
z
,而
%[^xyz]
读取的字符序列不是
x
y
z
。否则,它是文字:除了
%
之外,没有任何魔法字符,除了
%[…]
%c
之外的任何说明符都会在空白处停止。