简体   繁体   English

printf char数组段故障C

[英]printf char array segment fault C

So I have written a code that sorts words in the right order. 所以我写了一段代码,以正确的顺序对单词进行排序。 The words are being stored via pointers and I have initialized another char array in the program to store the char* argv . 单词是通过指针存储的,我已经在程序中初始化了另一个char数组,以存储char* argv

The last for loop is what prints segment fault and I can't figure out why. 最后一个for循环是打印段错误的原因,我不知道为什么。

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

int main(int argc, char* argv[]) {
  int i, j;
  char *key;
  char a[argc-1];
  for(i=1; i < argc; i++){
    a[i-1]= tolower(argv[i]);
      }

  for (i = 2; i < argc; i++) {
    key = argv[i];

    j = i-1;
    while (j >= 1 && strcmp(argv[j], key) > 0) {
      argv[j+1] = argv[j];
      j--;
    }

    argv[j+1] = key;
  }

  for(i = 1; i < argc; i++){
    a[i-1] = *argv[i];
  }

  for (i = 1; i < argc ; i++){
    puts(argv[i]);
  }

  for(i = 0; i < argc-1; i++){
    printf("%s", a[i]);
}
  return 0;
}

input 输入

./a.out orange banana apple

output 输出

apple
banana
orange
Segmentation fault

There are multiple problems in your code 您的代码中存在多个问题

  1. The line a[i - 1] = tolower(argv[i]) is wrong because tolower() takes int as paramater and you are passing char * so it's converting a pointer to int which is legal in c but does not guarantee defined behavior. a[i - 1] = tolower(argv[i])是错误的,因为tolower()int作为参数,并且您要传递char *因此它将指针转换为int ,这在c中是合法的,但不能保证定义的行为。

  2. You are not setting the '\\0' terminator on the a array which is another cause for problems, specifically when you try to use it as a string, a char array is not a string unless, it's a sequence of printable bytes with a terminating '\\0' byte. 您没有设置'\\0'上终止a数组这是另一种原因的问题,特别是当您尝试使用它作为一个字符串,一个char数组不是字符串,除非它是可打印的字节与终止序列'\\0'字节。

  3. Allocating argc - 1 is not going to work because 分配argc - 1不起作用,因为

    • The value of argc is the number of passed parameters to the executable. argc的值是传递给可执行文件的参数数。
    • If it was the length of the corresponding argv as found by strlen() you would need 1 more byte not less, so it would be argc + 1 in any case. 如果它是由strlen()找到的相应argv的长度,则需要不小于1个字节,因此在任何情况下argc + 1

Why are you using %s 为什么使用%s

for(i = 0; i < argc-1; i++){
printf("%s", a[i]);

try %c 尝试%c

Your compiler should also give you a warnging on: 您的编译器还应警告您:

printf("%s", a[i]);

warning: format specifies type 'char *' but the argument has type 'char' [-Wformat] 警告:format指定类型为'char *',但是参数为类型'char'[-Wformat]

If you change that to a %c it works fine . 如果将其更改为%c则可以正常工作

As the warning says, when you use it %s printf is expecting a string or a char* and will treat it as such. 如警告所言, %s printf在使用它时期望字符串或char* ,并将其视为此类。 a[i] is an integer type that can reference an invalid location in memory. a[i]是一个整数类型,可以引用内存中的无效位置。 So the correct way to do it would be to either use %c, and print a character; 因此,正确的方法是使用%c并打印一个字符; or use %s and pass a char* as the second argument. 或使用%s并将char *作为第二个参数传递。

Or perchance you want args in a. 或您可能想要args的性能。 Change the delcaration. 更改任务。

char *a[argc-1];

Then change the assignment. 然后更改分配。

a[i-1] = argv[i];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM