Странные символы появляются при использовании функции strcat в C ++ - PullRequest
1 голос
/ 06 декабря 2009

Я новичок в C ++ и учусь на MSDN C ++ для начинающих.

Пробуя функцию strcat, она работает, но я получаю три странных символа на начало.

Вот мой код

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main() {
    char first_name[40],last_name[40],full_name[80],space[1];
    space[0] = ' ';
    cout << "Enter your first name: ";
    gets(first_name);
    cout << "Enter your last name: ";
    gets(last_name);
    strcat(full_name,first_name);
    strcat(full_name,space);
    strcat(full_name,last_name);
    cout << "Your name is: " << full_name;
    return 0;
}

А вот и вывод

Enter your first name: Taher
Enter your last name: Abouzeid
Your name is: Y}@Taher Abouzeid

Интересно, почему Y} @ появляются перед моим именем?

Ответы [ 7 ]

8 голосов
/ 06 декабря 2009

Вы не инициализируете full_name, устанавливая первый символ в '\ 0', поэтому в нем есть символы мусора, а когда вы нажимаете strcat, вы добавляете новые данные после символов мусора.

4 голосов
/ 06 декабря 2009

Массив, который вы создаете, полон случайных данных. C ++ выделит пространство для данных, но не инициализирует массив с известными данными. Strcat прикрепит данные к концу строки (первый '\ 0'), так как массив символов не был инициализирован (и заполнен случайными данными), это не будет первый символ.

Это можно исправить, заменив

char first_name[40],last_name[40],full_name[80],space[1];

с

char first_name[40] = {0};
char last_name[40] = {0};
char full_name[80] = {0};
char space[2] = {0};

= {0} установит первый элемент в '\ 0', который является символом конца строки, а c ++ автоматически заполнит все не указанные элементы '\ 0' (при условии, что указан хотя бы один элемент).

2 голосов
/ 06 декабря 2009

Переменная full_name не инициализируется до добавления.

Изменить это:

strcat(full_name,first_name);

к этому:

strcpy(full_name,first_name);
1 голос
/ 06 декабря 2009

Вы не можете увидеть никаких проблем в своем тесте, но ваша строка space также не заканчивается нулем после инициализации единственного символа с ' '.

0 голосов
/ 06 декабря 2009

Строки заканчиваются нулем в C и C ++ (функция strcat является наследием C). Это означает, что когда вы указываете на случайный адрес памяти (новые переменные char [] указывают на адрес стека со случайным содержимым, которое не инициализируется), компилятор будет интерпретировать все, вплоть до первого \ 0 (нулевого) символа, как строку (и будет выходить за пределы выделенного размера, если вы используете арифметику указателей).

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

Вот хорошее резюме ваших вариантов .

0 голосов
/ 06 декабря 2009

Проблема с вашим space текстом.

Для функции strcat требуется строка в стиле C, которая содержит ноль или более символов, за которыми следует нулевой завершающий символ. Поэтому при выделении массивов для строк в стиле C вам нужно выделить один дополнительный символ для завершающего нулевого символа.

Итак, ваш space array needs to be of length 2, one for the space character and one for the null character. </p> <p> Since <code>space является константой, вы можете использовать строковый литерал вместо массива:

const char space[] = " ";<br>

Кроме того, поскольку вы новичок, вот несколько советов:
1. Объявите одну переменную на строку.
Это будет легче модифицировать и изменять типы переменных.

2. Либо очистите std::cout, используйте std::endl, либо добавьте '\ n'.
Это очистит буферы и отобразит любой оставшийся текст.

3. Прочтите FAQ по языку C ++.
Нажмите здесь для часто задаваемых вопросов (FAQ) по языку C ++

4. Вы можете избежать проблем со строками в стиле C, используя std :: string

5. Инвестируйте в Скотта Майерса Effective C ++ и More Effective C ++ books.

0 голосов
/ 06 декабря 2009

Как уже говорили другие, вы должны инициализировать данные, но задумывались ли вы когда-нибудь об изучении стандартной библиотеки c ++? Иногда это более интуитивно, и, вероятно, более эффективно.

С ним будет:

string full_name=first_name+" "+last_name;

, и вам не придется беспокоиться о завершающих нулевых символах. Для справки перейдите на cplusplus

Да, и полный рабочий пример, чтобы вы могли лучше понять (из оператора + =):

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string name ("John");
  string family ("Smith");
  name += " K. ";         // c-string
  name += family;         // string
  name += '\n';           // character

  cout << name;
  return 0;
}
...