【问题标题】:Why does my program not print the initials of a name? (CS50 Initials Program)为什么我的程序不打印姓名的首字母? (CS50 缩写程序)
【发布时间】:2015-12-17 11:13:29
【问题描述】:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>

int main(int argc, string argv[])
{
int i=0;
int x=0;
int n=0;

    argv[i]=GetString()
    printf("%c", toupper(argv[i][0]));
    for (x=0, n=strlen(argv[i]); x<n; x++)
    {
        printf("%c", toupper(argv[i+1][0]));
    }
    printf("\n");
}

代码编译但不打印用户输入的姓名的首字母。例如,John Smith: JS。相反,我收到了分段错误。

这个程序是 CS50 的 initials.c。

【问题讨论】:

  • printf("%c%c\n", argv[1][0], argv[2][0]); 如果你执行./a.out John Smith。如果GetString() 输入,请勿使用 argv。

标签: c arrays initializer-list cs50


【解决方案1】:

虽然您没有显示GetString() 的定义,但我很确定您没有正确调用它,因为它后面没有分号,而且您几乎肯定不想覆盖argv[0]。使用调试符号(GCC 中的-g)编译并在调试器中运行会告诉您哪一行代码导致程序崩溃。

编辑:我的猜测是,当您尝试取消引用 argv[i+1](即 argv[1]NULL 指针)时,您会崩溃。但是在调试器中运行可以确认或不确认这一点。您似乎将循环遍历参数列表的语法与从标准输入读取一行的语法混为一谈。

【讨论】:

  • 请注意,CS50 代码可在 CS50.net 上轻松获得 — 所有两个源文件(cs50.hcs50.c)都在一个 zip 文件中。它在 SO 上出现了相当多的情况。获得它可以让您编译和验证您对argv[i+1] 的观察。
  • 啊!第一次听说CS50。认为这是教授作为作业的一部分给出的东西。
【解决方案2】:

使用argv[0] 保存指向CS50GetString() 函数的返回值的指针是非正统的,尽管实际上并不违法。

您有语法错误; GetString() 后面省略了分号。

修复后,导致崩溃的问题在于循环中的索引;你正在索引argv[i+1][0],但argv[1] 是一个空指针,除非你提供了命令行参数并且访问空指针通常是一个崩溃(所以我们可以告诉你没有提供任何命令行参数)。

您可以通过以下方式进行演示:

$ ./initial xyz <<< "john smith"
JXXXXXXXXXX
$

它没有崩溃,它确实重复复制了转换为大写的参数的第一个字母(因为你一直在访问argv[i+1][0])。

相应的修复也很简单:

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

int main(void)
{
    int x = 0;
    int n = 0;

    string str = GetString();
    printf("%c", toupper(str[0]));
    for (x = 0, n = strlen(str); x < n; x++)
    {
        printf("%c", toupper(str[x]));
    }
    printf("\n");
    free(str);
    return 0;
}

示例运行

$ ./initials <<< "john smith"
JJOHN SMITH
$

这不是必需的输出,但它确实表明程序安全运行,并为您提供了一个良好的基础,可以从中获得正确的答案。

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多