0

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.

The last for loop is what prints segment fault and I can't figure out why.

#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
12
  • 1
    tolower(argv[i]) should be rasing a warning from the compiler, otherwise it's because you did not enable them, do not ignore them at all! Warnings are very useful for expert programmers, thy must be a tool for non experts. Commented Nov 21, 2016 at 14:28
  • @iharob i commented that part out. Yet i am still getting segment fault. Commented Nov 21, 2016 at 14:38
  • Please read my answer ... let the compilation warnings guide you. I mean, try to understand the warnings and infer the way things work from that. Commented Nov 21, 2016 at 14:39
  • Can you include the actual inputs and outputs. Commented Nov 21, 2016 at 14:41
  • @matt posted in my topic a sample input and output Commented Nov 21, 2016 at 14:48

3 Answers 3

1

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]

If you change that to a %cit works fine.

As the warning says, when you use it %s printf is expecting a string or a char* and will treat it as such. a[i] is an integer type that can reference an invalid location in memory. So the correct way to do it would be to either use %c, and print a character; or use %s and pass a char* as the second argument.

Or perchance you want args in a. Change the delcaration.

char *a[argc-1];

Then change the assignment.

a[i-1] = argv[i];
Sign up to request clarification or add additional context in comments.

2 Comments

Your Answer doesn't seem to explain the actual problem, it offers a Code-Fix. If you change that to a %cit works fine. Is not really an Answer.
@Michi it can be improved. I think the actual problem was they wanted an array of char* but instead they just had a char, so discussing the %c behavior seems a bit irrelevant.
1

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.

  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.

  3. Allocating argc - 1 is not going to work because

    • The value of argc is the number of passed parameters to the executable.
    • 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.

Comments

0

Why are you using %s

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

try %c

5 Comments

%c would just print the first letter of each word.
Shouldn't your a be char *a[argc] rather than char a[argc]
No because argc is 4 in case of an input that 3 words. argc also counts main()
No i mean character pointer to array rather than character array. 'char *a[argc-1] ' rather than 'char a[argc-1]' notice the pointer.
That works but my main goal to achieve from this program is to be able to take text and start words into and array and print the words alphabetically without duplicates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.