CS50:pset2/首字母:-I';我有一些代码可以工作,但我觉得我在设置数组大小方面走了一条捷径

CS50:pset2/首字母:-I';我有一些代码可以工作,但我觉得我在设置数组大小方面走了一条捷径,c,arrays,cs50,C,Arrays,Cs50,因此,我一直在研究CS50中首字母缩写问题的“不太舒服”版本,在开始编写非常详细的代码后,我设法将其简化为: #include <cs50.h> #include <ctype.h> #include <stdio.h> #include <string.h> int c = 0; int main(void) { string name = get_string(); int n = strlen(name); ch

因此,我一直在研究CS50中首字母缩写问题的“不太舒服”版本,在开始编写非常详细的代码后,我设法将其简化为:

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

int c = 0;

int main(void)
{
    string name = get_string();
    int n = strlen(name);

    char initials[10];

    // first letter is always going to be the first initial
    initials[0] = name[0];

    // count through letters looking for spaces + add the first letter after a 
    // space to the initials array
    for (int j = 0; j < n; j++)
    {
        if (name[j] == 32)
        {
            c += 1;
            initials[c] += name[j+1];
        }
    }    

    // print out initials
    for (int k = 0; k <= c; k++)
    {
        printf("%c", toupper(initials[k]));
    }    

   printf("\n"); 
} 
#包括
#包括
#包括
#包括
int c=0;
内部主(空)
{
string name=get_string();
int n=strlen(名称);
字符首字母[10];
//第一个字母总是第一个字母
姓名首字母[0]=姓名[0];
//通过字母进行计数,查找空格+在空格后添加第一个字母
//将空格添加到初始值数组
对于(int j=0;j对于(int k=0;k首先,请记住,执行速度通常比内存使用更有价值。如果首先查找空间,然后分配内存,则必须在数组中迭代两次。这是以执行速度为代价的内存使用优化。因此,只分配一个“足够大”的数组,比如说100个字符,并保留您拥有的代码

然后我想将数组[spaces+1]设为如果有2个空格,那么将有3个首字母

请记住,C字符串是以null结尾的,因此您也需要为null结尾符分配空间,
spaces+1+1

当我上传代码进行检查时,仅使用此“for”循环编译代码会返回一个失败(尽管它编译起来没有问题)。即使我不使用任何“for”循环输出,但它存在的事实也会导致此错误

什么错误?编译还是不编译,你的文本是矛盾的

确保将
空格
初始化为零


作为旁注,切勿在C代码中使用“幻数”。
如果(name[i]==32)
,32对于无法通过内存引用ASCII表的任何人来说都是胡言乱语。此外,对于具有其他可能没有相同索引号的符号表的系统,它是不可移植的。请改为编写:

if (name[i] == ' ')

在我看来,满足这种情况的一个好方法是库函数
snprintf
使用的方法:它要求您传入要填充的字符串以及该字符串的大小。In确保字符串不会被覆盖,并且字符串以零结尾

如果字符串足够大,函数将返回写入字符串的字符长度。您现在可以执行以下两种操作之一:猜测合理的缓冲区大小,并接受字符串偶尔会被缩短。或者使用零长度调用函数,使用返回值分配一个字符缓冲区,然后用第二个电话

将此方法应用于您的姓名首字母问题:

int initials(char *ini, int max, const char *str)
{
    int prev = ' ';         // pretend there's a space before the string
    int n = 0;              // actual number of initials

    while (*str) {
        if (prev == ' ' && *str != ' ') {
            if (n + 1 < max) ini[n] = *str;
            n++;
        }

        prev = *str++;
    }

    if (n < max) {
        ini[n] = '\0';
    } else if (max > 0) {
        ini[max] = '\0';
    }    

    return n;
}
或两步动态大小方法:

char *name = "Theodore Quick Brown Fox";

char ini[4];
initials(ini, sizeof(ini), name);

puts(ini);        // prints "TQB", "F" is truncated
char *name = "Theodore Quick Brown Fox";
int n;

n = initials(NULL, 0, name);

char ini[n + 1];
initials(ini, sizeof(ini), name);

puts(ini);        // prints "TQBF"

(请注意,
initals
的此实现将忽略多个空格和字符串末尾或开头的空格。在这种情况下,先行查找函数将插入空格。)

您知道您的
initials
数组不能比名称本身大;最多不能超过名称本身的一半(其他每个字符都是一个空格)。因此请将其用作大小。最简单的方法是使用可变长度数组:

size_t n = strlen( name ); // strlen returns a size_t type, not int

char initials[n/2+1];         // n/2+1 is not a *constant expression*, so this is
                              // a variable-length array.
memset( initials, 0, n + 1 ); // since initials is a VLA, we can't use an initializer
                              // in the declaration.
唯一的问题是,VLA支持可能不确定-VLA是在C99中引入的,但在C2011中是可选的

或者,您可以使用动态分配的缓冲区:

#include <stdlib.h>
...
size_t n = strlen( name );

char *initials = calloc( n/2+1, sizeof *initials ); // calloc initializes memory to 0

/**
 * code to find and display initials
 */

free( initials );  // release memory before you exit your program.  
或者使用
isspace
library函数(对于空格、制表符、换行符等将返回true):

#包括
...
if(isspace(name[j]))

你为什么还要存储呢?只需将它打印出来就行了……否则,我打赌,计算出元素的数量,然后使用VLA。
char*initials=malloc(spaces+1);
就像你的数组一样使用,但在使用完后调用
free(initials);
char initials[spaces+1]
您得到编译错误还是运行时错误?如果您有一行包含“
john q doe
”,则有2个空格,但有3个单词需要转换为首字母,因此您需要一个大小为4的数组来允许终端空字节-即空格数加2。您应该使用
'
来表示空格,而不是
32
#include <stdlib.h>
...
size_t n = strlen( name );

char *initials = calloc( n/2+1, sizeof *initials ); // calloc initializes memory to 0

/**
 * code to find and display initials
 */

free( initials );  // release memory before you exit your program.  
if ( name[j] == ' ' )
#include <ctype.h>
...
if ( isspace( name[j] ) )