简体   繁体   English

C ++:打印/分配简单数组打印乱码

[英]C++: Printing/assigning simple array prints gibberish

My code basically is to list ASCII codepoints of a string that is input, my following code is simple, here: 我的代码基本上是列出输入字符串的ASCII码点,我的以下代码很简单,在这里:

#include <iostream>
#include <string.h>

using namespace std;

int main() {
    char str[20];
    int result[20];
    cin >> str;

    for(int i = 0; i != strlen(str); i++) {
        result[i] = (int)i; 
    }

    for(int i = 0; i != 20; i++)
        cout << result[i] << ", "; 
}

when I run it, no matter what the input it outputs a pile of gibberish like undefined memory like so: 当我运行它时,无论输入什么,它都会输出一堆乱码,如未定义的内存,如下所示:

0, 1, 2, 3, 4, 5, 1, -1217349408, -1220040795, -1220041307, -1076427112, 134514781, -1218903292, 134519344, -1076427096, 134514004, -1217411568, 134519344, -1076427048, 134514681,

Am I missing something simple in how I append each integer to the array? 我在将每个整数附加到数组上时是否缺少一些简单的方法?

Just note this is a simple example, my input will not be larger than 20 characters. 请注意,这是一个简单的示例,我的输入将不超过20个字符。

EDIT Typo in my result.. cin>>result was cin>>str 在我的结果中编辑 Typo。.cin >>结果为cin >> str

This loop will iterate a number of times equal to the length of 'str'. 此循环将迭代等于“ str”长度的次数。 That is, it will iterate once for each character in 'str', and stop at the 'null terminator' (char value of 0) which is how c strings are ended. 也就是说,它将对“ str”中的每个字符进行一次迭代,并在“ null终止符”(char值为0)处停止,这就是c字符串结束的方式。 In each loop, the value of 'i' is the loop number, starting at 0 - and this is the value you assign to that index in the results array. 在每个循环中,“ i”的值是循环号,从0开始-这是您分配给结果数组中该索引的值。

for(int i = 0; i != strlen(str); i++) {
    result[i] = (int)i; 
}

So for example, for a string of length 5, you will assign the values '0, 1, 2 ,3, 4' to the result array at those indexes, respectively. 因此,例如,对于长度为5的字符串,您将在这些索引处分别将值'0、1、2、3、4'分配给结果数组。 The other values in the result array are not assigned - and so could hold any value (generally, whatever was in that bit of memory before you started using it). 结果数组中的其他值未分配-因此可以保存任何值(通常,在开始使用它之前,该位内存中的任何值)。 If your string is longer than 20 characters, you're in trouble, because you will start trying to access the array at index 20 and beyond, which is not memory that belongs to your program. 如果您的字符串长度超过20个字符,则可能会遇到麻烦,因为您将开始尝试访问索引为20及更高位置的数组,该数组不是属于您程序的内存。

This loop prints out all the values in the 'result' array, from the value at index 0 to the value at index 19: 该循环打印出“结果”数组中的所有值,从索引0的值到索引19的值:

for(int i = 0; i != 20; i++)
    cout << result[i] << ", "; 

So it will print the initialised values, and, if the string was less than 20 characters long, the uninitialised values as well. 因此它将打印初始化值,如果字符串的长度少于20个字符,则还将打印未初始化的值。

At a minimum, to start getting anything like the results you're after, you want to change 至少要开始获得类似您想要的结果,您需要进行更改

result[i] = (int)i; 

to

result[i] = str[i];

but as mentioned by others, and to escape some of the memory access issues I mentioned above, it would be much better if you use an iterator to get the character values. 但是正如其他人所提到的,为了避免我上面提到的某些内存访问问题,如果使用迭代器来获取字符值会更好。

for(string::iterator i = str.begin(); i != str.end(); i++)
  // access char here using '*i'

strlen(str)将为您提供未定义的输出,因为您尚未初始化str[]的内容。

You have 3 problems: 您有3个问题:

  1. You didn't initialise str with a proper string, thus strlen will return an unpredictable value. 您没有使用适当的字符串初始化str ,因此strlen将返回不可预测的值。
  2. You initialise the first strlen(str) positions of result , but later you print it until the index 20. You should use the same condition on both loops. 初始化result的第一个strlen(str)位置,但随后将其打印到索引20。在两个循环中应使用相同的条件。
  3. You should definitely use std::string and its iterator. 您绝对应该使用std::string及其迭代器。

Essentially, you failed to correctly initialize the string and you didn't check that it was the correct size. 本质上,您无法正确初始化字符串,也没有检查它的大小是否正确。 Correct code: 正确的代码:

#include <iostream>
#include <string> // NOT <string.h>, <string>

int main() {
    std::string str;
    std::cin >> str;
    std::cin.ignore();
    for(std::string::iterator it = str.begin(); it != str.end(); it++) {
        std::cout << (int)(*it);
        if (it + 1 != str.end())
            std::cout << ", ";
        else
            std::cout << "\n";
    }
    std::cin.get();
}

You've not initialized str and you are taking its strlen 你没有初始化str和你正在服用它strlen

When you did 当你做了

cin >> result; // this does not even compile!!!

I guess you meant 我想你是说

cin >> str;

Its not clear what you are trying to do. 目前尚不清楚您要做什么。 But you can try this to get some meaningful result: 但是您可以尝试这样做以获得一些有意义的结果:

char str[20];
int result[20] = {0};
cin >> str;
...// rest all unchanged.

stlen( str ) will give the number of characters before the null terminator . stlen( str )将给出空终止之前的字符数。

This means that only strlen(str) integers are valid. 这意味着仅strlen(str)整数有效。 The rest are uninitialized. 其余的未初始化。

Also: have a look at std::transform . 另外:看看std::transform You can avoid the temporary array of integers to achieve the same, or transform right into one. 您可以避免使用临时整数数组来实现相同目的,也可以transform直接转换为一个。

int to_codepoint( char c ) { return (int) c; }


// ...
char cs[] = "abcd";
std::transform( cs, cs+strlen(cs)
             , std::ostream_iterator<int>( std::cout, ", " ), to_codepoint);

// or transform into an array:
int is[ 1000 ]; // 1000 enough?
std::transform( cs, cs+strlen(cs)
              , is, to_codepoint );

( test code at codepad.org ) 位于codepad.org的测试代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM