strcat () удаляет строки при попытке создать разделенную пробелами строку.(C программирование) - PullRequest
1 голос
/ 09 октября 2011

Я боролся с этой проблемой в течение последних нескольких часов, и это одна из странных проблем, с которыми я столкнулся за 3 года обучения программированию.

Я пытаюсь создать более длинную строку, разделенную пробелами, путем объединения строк, найденных в argv из stdin.Это код, который я первоначально написал:

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

#include "stringtable.h"
#include "strhash.h"
#include "auxlib.h"


int main (int argc, char **argv) {
    int c;
    char* filename;

    while((c = getopt(argc, argv, "@:Dly")) != -1){
        switch(c){
            case '@': 
                printf("@ detected\n");
                char* debugString = optarg;
                int pos_in_input = optind;
                while(argv[pos_in_input][0] != '-' && argv[pos_in_input] != NULL){
                    strcat(debugString, " ");
                    strcat(debugString, argv[pos_in_input]);
                    pos_in_input++;
                    if(argv[pos_in_input] == NULL){break;}                  
                }
                printf("%s\n", debugString);
                break;
            case 'D':
                printf("D detected\n");
                break;
            case 'l':
                printf("l detected\n");
                break;
            case 'y':
                printf("y detected\n");
                break;
            default :
                printf("default detected\n");
        }
    }
}

Большинство из вышеперечисленного - это моя незаконченная обработка опций.Интересующий сегмент кода находится в операторе switch в регистре: «@».Предполагается, что цикл while создает debugString, объединяя строки, найденные в argv, и останавливается, когда строка начинается с «-» или когда достигается конец argv.Я также добавляю пробелы между строками с помощью "strcat (debugString," ");"Это добавляет пробелы, которые доставляют мне проблемы.

Если я объединяю все строки без добавления пробелов таким образом:

            while(argv[pos_in_input][0] != '-' && argv[pos_in_input] != NULL){
                strcat(debugString, argv[pos_in_input]);
                pos_in_input++;
                if(argv[pos_in_input] == NULL){break;}                  
            }

Я получаю следующее:

 Input: -@what is going on here?
Output: @ detected
        whatisgoingonhere?

Вот как я ожидал, что это сработает.Однако, если я запускаю код, который добавляет пробелы:

            while(argv[pos_in_input][0] != '-' && argv[pos_in_input] != NULL){
                strcat(debugString, " ");
                strcat(debugString, argv[pos_in_input]);
                pos_in_input++;
                if(argv[pos_in_input] == NULL){break;}                  
            }

Затем я получаю следующее:

 Input: -@what is going on here?
Output: @ detected
        what  going on here?

Обратите внимание на два пробела между «что» и «происходит».Моя программа все еще правильно добавляет пробелы, хотя по какой-то причине слово удаляется.Я пробовал это со многими различными входами, это всегда вторая строка ввода, которая удаляется.Кто-нибудь знает, что происходит?

PS Компиляция с помощью gcc -g -O0 -Wall -Wextra -std = gnu99 -lm

Ни один из созданных мной включаемых файлов не используется в этой частикода, так что проблема не что-то в моем включает.

1 Ответ

1 голос
/ 09 октября 2011

Ваш интересующий код начинается с:

            char* debugString = optarg;

Это делает указатель debugString на то же место , на которое указывает optarg.Это никак не выделяет «новую» строку.Вызывая strcat(debugString, ...), вы перезаписываете то, что еще появляется в памяти после окончания optarg.Будет хаос.

Чтобы решить эту проблему, попробуйте:

            char debugString[1000];
            strcpy(debugString, optarg);

Это выделит вам 1000 байт для добавления битов строки в strcat.Это ваша ответственность за то, чтобы вы не писали после конца debugString буфера (так что если вы обнаружите, что у вас есть более 1000 байтов для объединения, вам придется решить, что вы хотитеделать с этим).

...