2015-10-26 2 views
0

Я пытаюсь создать программу, которая читает файл, содержащий буквы [a-z]. Затем я замените с 1, е с 2, я с 3, о с 4 и у с 5. Я запустить программу с вводе команды Удаление первого символа из строки приводит к ошибке сегментации

./tr AEIOU 12345 < data.txt // Нет пространства между < и data.txt

Мой код:

#include<stdio.h> 

int main(int argc, char **argv) 
{ 
    FILE *fp; 
    fp = fopen(argv[3], "r"); 
    char input[100]; 
    fscanf(fp, "%[^\n]", input); 
    int a = 0, b = 0; 
    if(argv[3][0] == '<') { 
     (*(argv[3]))++; //SEGFAULT 
    } 
    while(input[a] != '\0') { 
     if(input[a] == argv[1][b]) { 
      input[a] = argv[2][b]; 
      ++b; 
     } 
     ++a; 
    } 
    printf("%s", input); 
    fclose(fp); 
    return 0; 
} 

Если я запустить программу с

./tr AEIOU +12345 data.txt // Обратите внимание, не <

Затем он работает нормально, но это дает мне Сегментация ошибку, когда я запускаю его с <. Почему это? По моему мнению, он не должен занимать больше памяти, просто переместив указатель на один символ вправо.

Есть ли более простой способ сделать это? Какие-либо предложения? Спасибо

+1

Думаю, вы обнаружите, что 'argv [3]' равно null. Для подтверждения используйте отладчик. Вы должны проверить 'argc' и помнить, что C запускает массивы с индексом нуля. –

+1

@EdHeal вы правы, но 'argv [0] =./Tr' – JackVanier

+0

Где же командной строки разделяется между материалами, которые использует оболочка, и программа использует? Просто проверьте значение 'argc' –

ответ

3

Проблема заключается в том, что независимо от того, есть ли у вас пробел между < и data.txt, < будет интерпретироваться оболочкой как оператором ввода файла и, таким образом, не будет передаваться в программу. Я написал следующий фрагмент в C:

#include <stdio.h> 

int main(int argc, char **argv) { 
    for (int i = 0; i < argc; i++) { 
    printf("%s \n", argv[i]); 
    } 
} 

Который только распечатывает все аргументы. Вызов ./test.out aeiou 12345 дает:

./test.out 
aeiou 
12345 

как ожидалось. Но вызов ./test.out aeiou 12345 <6789 приведет к тому, что терминал пожалуется, что нет такого файла 6789. Затем я создал файл с именем 6789, содержащий текст «6789». Но это не будет иметь никаких последствий. Выход остается:

./test.out 
aeiou 
12345 

Проблема в коде точно, что argv[3] равна нулю. data.txt передается на вход, но не в виде argv.

+1

«data.txt передается во вход, но не в виде argv» - только если программа * потребляет * вход из 'stdin', в который будет перенаправлен текст из этого файла. Программа OP не использует 'stdin'. – usr2564301