Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何声明字符串以使其';s的长度由用户在c中给出?_C_String - Fatal编程技术网

如何声明字符串以使其';s的长度由用户在c中给出?

如何声明字符串以使其';s的长度由用户在c中给出?,c,string,C,String,所以我被要求这样做,我是这样做的: #include <stdio.h> #include <stdlib.h> int main(void) { int N,i; printf("Give the number of char's you want to input.\n"); scanf("%d",&N); char *str = (char*)

所以我被要求这样做,我是这样做的:

    #include <stdio.h>
    #include <stdlib.h>

    int main(void)
    {        
        int N,i;
        printf("Give the number of char's you want to input.\n");
        scanf("%d",&N);

        char *str = (char*) malloc(N);

        //this segment inputs the char's to the string.
        printf("Input the char's.\n"); 
        for (i=0;i<N;i++)
        {
           str[i] = getchar();
        }
        str[N] = '\0';
    }
#包括
#包括
内部主(空)
{        
int N,i;
printf(“给出要输入的字符数。\n”);
scanf(“%d”和“&N”);
char*str=(char*)malloc(N);
//此段将字符输入字符串。
printf(“输入字符。\n”);
对于(i=0;i使用a(C99和更高版本中允许)或使用。您的方法是使用VLA。您也可以通过以下方式动态执行此操作:

int N;
printf("Give the number of char's you want to input.\n");
scanf("%d",&N);

char *str = malloc(N+1);  

旁注:

  • main
    更改为其正确的签名
    int main(void)
  • 数组索引从C中的
    0
    开始。将
    i
    初始化为
    0
    而不是
    1
    ,并将上限设置为
    i
    。将
    for
    循环更改为
for(int i=0;i
  • 根据建议,不要使用
    scanf
    ,尤其是
    grtchar

    改用

我相信使用诸如
malloc()
之类的动态内存分配是解决问题的更好方法,这意味着

char str[N+1];
你应该这样做

char *str = malloc(N+1);

不要忘记在使用完内存后通过
free(str);
释放内存。

C99支持您尝试执行的操作。GCC从C90支持这一点

但实际上这是一种不好的实现方式。这样的数组是在堆栈上分配的。这可能非常有用,因为它们的分配和释放速度非常快,但这种方法可能会导致堆栈溢出


通常这类任务是使用动态分配实现的。请参阅malloc和free的文档。可以找到更完整的文档和示例

更好的方法是使用
fgets()
并建议测试用户输入结果

printf("Give the number of char's you want to input.\n");

buf[40]; 
if (fgets(buf, sizeof(buf), stdin) == NULL) {
  Handle_EOForIOError();
}
int n;  // Suggest lower case 'n'
if (sscanf(buf, "%d", &n) != 1) Handle_SyntaxError();

char str[n+2];  // OP's VLA

if (fgets(str, sizeof(str), stdin) == NULL) {
  Handle_EOForIOError();
}

// Trim the \n if needed
size_t len = strlen(str);
if (len > 0 && str[len-1] == '\n') str[--len] = '\0'; 

你应该在
i=0
开始写入你的字符串:
for(i=0;这不是正确的C,任何支持你正在使用的功能的编译器都应该告诉你。我不知道你从哪一个古老的代码复制了它,但是
main()
应该是
int main(void)
@Jens Gustedt我自己写的。我使用devc++但它从不抱怨though@Mechanic45,然后您应该查找编译器的选项以提高警告级别。@Jens ok,谢谢您更改了它。+1但请不要鼓励使用
scanf()
。谢谢你的回答。大家有什么特别的理由建议不要像我那样使用for循环的特定限制吗?好的,将建议的更改应用到代码中。但是关于最后一个。如果我不应该使用scanf,那么是哪一个?@Mechanic45;添加了答案的链接。嗯..关于malloc..我收到了这个警告和程序m故障。[警告]内置函数“malloc”的不兼容隐式声明[默认启用]但实际上,这是一种糟糕的实现方式:我不同意,除非你需要大的内存空间。嗯,你知道,我喜欢在堆栈上分配对象。它们很快,它们是本地的,在释放时不会造成内存浪费。但是在这种特殊情况下,用户指定数组的长度。输入字符串也是用户提供的。Bo这些参数没有经过净化。事实上,这种方法是网络中大多数裂缝和漏洞的原因。当然,我知道这只是一个新手C程序员编写的示例代码。不过,最好是通过仔细的示例自学。@H2CO3不,你不能将VLA与MSVC一起使用(可能与其他编译器一起使用)VisualC++是不是C编译器。你不能用VLAs和任何C++编译器,因为VLAS不是C++的一部分。所以这与Windows完全无关。(即使VC++是一个C编译器,您的论点仍然没有意义,因为还有其他针对Windows的C编译器,例如支持C99和VLAs的GCC。)@H2CO3我认为在使用语言功能之前,最好知道在哪里可以编译它。你可能不想因为VLA@Ubiquit当然,但在这种情况下,OP不需要更改编译器——他已经在编写C代码了(如果我们相信他问题上的标记的话)。(另外,我知道Visual Studio附带了一个很少使用的C编译器,但不幸的是,它不支持C99…真遗憾!)@H2CO3 MSVC很少使用!你从哪里得到这些奇怪的信息?
printf("Give the number of char's you want to input.\n");

buf[40]; 
if (fgets(buf, sizeof(buf), stdin) == NULL) {
  Handle_EOForIOError();
}
int n;  // Suggest lower case 'n'
if (sscanf(buf, "%d", &n) != 1) Handle_SyntaxError();

char str[n+2];  // OP's VLA

if (fgets(str, sizeof(str), stdin) == NULL) {
  Handle_EOForIOError();
}

// Trim the \n if needed
size_t len = strlen(str);
if (len > 0 && str[len-1] == '\n') str[--len] = '\0';