Странные символы появляются при использовании функции strcat в C ++

StackOverflow https://stackoverflow.com/questions/1853619

  •  13-09-2019
  •  | 
  •  

Вопрос

Я новичок в 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}@ появляется перед моим именем ?

Это было полезно?

Решение

Массив, который вы создаете, полон случайных данных.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' (при условии, что указан хотя бы один элемент).

Другие советы

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

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

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

strcat(full_name,first_name);

к этому:

strcpy(full_name,first_name);

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

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

С этим было бы:

string full_name=first_name+" "+last_name;

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

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

#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;
}

Проблема заключается в вашем space текст.

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

Итак, ваш space array needs to be of length 2, one for the space character and one for the null character.

С тех пор как space является константой, вы можете использовать строковый литерал вместо массива:

const char space[] = " ";

Also, since you are a newbie, here are some tips:
1. Declare one variable per line.
This will be easier to modify and change variable types.

2. Either flush std::cout, use std::endl, or include a '\n'.
This will flush the buffers and display any remaining text.

3. Read the C++ language FAQ.
Нажмите здесь, чтобы ознакомиться с часто задаваемыми вопросами по языку C ++ (FAQ)

4. You can avoid C-style string problems by using std::string


5.Инвестируйте в Скотта Майерса Эффективный C++ и Более эффективный C ++ Книги.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top