символ мусора в конце строки? - PullRequest
2 голосов
/ 21 августа 2010

Привет! Я читаю строку, разбиваю каждое слово и сортирую его по имени, электронной почте и номеру телефона. со строкой joe bloggs joeblog@live.com 12345. Но как только я разбил все на части, отдельные разделенные переменные, которые содержат имя, адрес электронной почты и номер телефона, имеют в конце символы мусора. Я не могу понять, почему.

тестовый файл

//test file
#include <iostream>
#include <string>
#include "iofunc.h"
using namespace std;
int main(){
    string str1 = "joe bloggs joeblog@live.com 12345";

    iofunc func;
    cout<<"|-----------------------getname DEMONSTRATION------------------|\n" << endl;
    func.getName(str1);

    cout<<"the names are: " << func.glob_name << endl;

    cout<<"\n|-----------------------getphone DEMONSTRATION------------------|\n" << endl;
    func.getPhone(str1);
    cout<<"the phone number is:" << func.glob_phone << endl;

    cout<<"\n|-----------------------getemail DEMONSTRATION------------------|\n" << endl;
    func.getEmail(str1);
    cout<<"the email address is:" << func.glob_email << endl;


    return 0;
}

вот моя функция get name, класс слишком большой для прокрутки:)

void iofunc::getName(string arg){
    lineProcess(arg); 
    //make sure to call this depending on what function u are using

    int name_count = 0;
    int wspace_count = 0;
    int arg_len = arg.length();
    //int char_len = 0;
    char name_temp[80];

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function

    //for special, condition when there is no space in front of names
    if (special_condition == true){
        int i = 0;
        while(i < arg_len){
            name_temp[i] = arg[i];
            i++;
        }
        glob_name = string(name_temp);

    }

    if (special_condition == false){
        if (name_count == 1){
            int i = 0;
            while (arg[i] != ' '){
                name_temp[i] = arg[i];
                i++;
            }
            glob_name = string(name_temp);
        }

        //for 2 names
        if (name_count == 2){
            for (int i = 0; i < arg_len;i++){
                if (arg[i] == ' '){
                    wspace_count++;
                }
                if (wspace_count !=2){
                    name_temp[i] = arg[i];
                }
            }
            glob_name = string(name_temp);
        }
        //for 3 names
        if (name_count == 3){
            for (int i = 0; i < arg_len;i++){
                if (arg[i] == ' '){
                    wspace_count++;
                }
                if (wspace_count !=3){
                    name_temp[i] = arg[i];
                }
            }
            glob_name = string(name_temp);
        }
    }

}

Базовый список всего этого, я использую функцию lineProcess, чтобы выяснить, есть ли электронная почта, телефон и имя в строке аргумента. А функции numberofNames дают количество имен, чтобы я мог действовать соответственно.

Мне пришлось использовать char name_temp, чтобы скопировать только имена из строки, чтобы я мог извлечь только это и присвоить его переменной string с именем glob_name. Он копирует все, что мне нужно, но выдает мне этот мусор после каждой извлеченной строки.

Есть идеи?

EDITED

void iofunc::getName(string arg){
    lineProcess(arg); 
    //make sure to call this depending on what function u are using

    int name_count = 0;
    int wspace_count = 0;
    int arg_len = arg.length();
    //int char_len = 0;
    char name_temp[80];
    int index_track = 0;

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function

    //for special, condition when there is no space in front of names
    if (special_condition == true){
        int i = 0;
        while(i < arg_len){
            name_temp[i] = arg[i];
            index_track = i;
            i++;
        }
        name_temp[index_track+1] = '\0';
        glob_name = string(name_temp);

    }

    if (special_condition == false){
        if (name_count == 1){
            int i = 0;
            while (arg[i] != ' '){
                name_temp[i] = arg[i];
                index_track = i;
                i++;
            }
            name_temp[index_track+1] = '\0';
            glob_name = string(name_temp);
        }

        //for 2 names
        if (name_count == 2){
            for (int i = 0; i < arg_len;i++){
                if (arg[i] == ' '){
                    wspace_count++;
                }
                if (wspace_count !=2){
                    name_temp[i] = arg[i];
                    index_track = i;
                }
            }
            name_temp[index_track+1] = '\0';
            glob_name = string(name_temp);
        }
        //for 3 names
        if (name_count == 3){
            for (int i = 0; i < arg_len;i++){
                if (arg[i] == ' '){
                    wspace_count++;
                }
                if (wspace_count !=3){
                    name_temp[i] = arg[i];
                    index_track = i;
                }
            }
            name_temp[index_track+1] = '\0';
            glob_name = string(name_temp);
        }
    }

}

Ответы [ 4 ]

2 голосов
/ 21 августа 2010

добавить к каждой новой строке '\ 0' символ конца строки

0 голосов
/ 21 августа 2010

Другие указали вам правильное направление, вы не правильно завершаете свои строки c. Объявление массива char длиной 80 просто указывает на блок памяти, он никак не инициализирует массив, это означает, что если вы / 0 не завершите строку, в которую вы копируете, вы получите всю хрень, лежащую вокруг в конце до 80 символов.

Я не писал C ++, вероятно, в течение 15 лет, поэтому приведенный ниже код может даже не работать, но, надеюсь, он даст вам некоторые идеи для более элегантного и удобного в обслуживании решения.

void iofunc::getName(string arg){
    lineProcess(arg); 
    //make sure to call this depending on what function u are using

    int name_count = 0;
    int wspace_count = 0;
    int arg_len = arg.length();
    //int char_len = 0;
    string name_temp;

    // Let's assemble a c-str version if the inbound arg string
    char* cstr;
    cstr = new char [arg.size()+1];
    strcpy (cstr, arg.c_str());

    name_count = numberofNames(); 
    //line process was called before so this will work, 
    //make sure you call line process before using this function

    //for special, condition when there is no space in front of names
    if (special_condition == true){
        glob_name = arg;
    }

    if (special_condition == false){
        // Assuming there's at least 1 name, which we have to otherwise the original
        // code may never set glob_name, let's use the C String function strtok
        // to tokenise our newly created c string at each " ".
        // Grab the first name.
        name_temp = string(strtok(cstr, " "));
        for (int i = 1; i < name_count; i++) {
            // Grab names 2 to name_count as required and append them to name_temp
            // We need to reinsert the space as strtok doesn't grab it.
            name_temp += " " + string(strtok(NULL, " "));
        }
        // Assign our final name to glob_name
        glob_name = name_temp;
    }

}
0 голосов
/ 21 августа 2010

Когда вы делаете такие вещи:

    while(i < arg_len){ 
        name_temp[i] = arg[i]; 
        i++; 
    } 

Вы копируете символы строки в name_tmp, но не 0 в конце, который завершает строку.

0 голосов
/ 21 августа 2010

Символы мусора в конце строки могут указывать на то, что строка не заканчивается на ноль (заканчивая ее байтом 0x00). Это приводит к тому, что строка продолжает читать до следующего нулевого символа, который фактически находится за пределами конца памяти строки. Это может даже вызвать ошибку сегментации в некоторых случаях.

Вы можете исправить это, добавив '\0' в конец каждой новой строки, которую вы создаете. Обратите внимание, что теперь вам нужно будет выделить строку на один байт больше, чтобы сохранить этот новый завершающий символ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...