简体   繁体   English

在 C++ 中显示不需要的数字

[英]Displaying unwanted numbers in C++

Okay so I've been working on a school project with C++.好的,所以我一直在使用 C++ 进行学校项目。 I have to enter my name and when I do, the letters from my input shall be converted into integers.我必须输入我的名字,当我输入时,我输入的字母将被转换为整数。 The letters have their own corresponding numbers from 1 to 26 for a to z accordingly.相应地,字母从 1 到 26 对应于 a 到 z。 So I figured maybe I could use this:所以我想也许我可以使用这个:

int main(int argc, char** argv) {

    char lowletters[26] = {'a', 'b', 'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    char upletters[26]  = {'A', 'B', 'C', 'D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
    char fname[50], lname[50];
    int corrNums[26] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26};

    cout << "Enter name: ";
    cin >> fname >> lname;

    for(int a = 0; a <= sizeof(fname)-1; a++){
        for(int b = 0; b < 26; b++){
            if(fname[a] == lowletters[b]){  
                cout<<corrNums[b]<<"\t";
            }
            if(fname[a] == upletters[b]){   
                cout<<corrNums[b]<<"\t";
            }
        }
    }

     for(int a = 0; a <= sizeof(lname)-1; a++){
        for(int b = 0; b < 26; b++){
            if(lname[a] == lowletters[b]){  
                cout<<corrNums[b]<<"\t";
            }
            if(lname[a] == upletters[b]){   
                cout<<corrNums[b]<<"\t";
            }
        }
    }

    return 0;   
}

So I used the first loop to get the characters from the fname and compare it to the lowercased and uppercased letters to find what letter it is.所以我使用第一个循环从 fname 中获取字符并将其与小写和大写字母进行比较以查找它是什么字母。 When it does, it would display the corrNums(corresponding numbers) with the value of b in the for loop so that it would match.当它这样做时,它将在 for 循环中显示带有 b 值的 corrNums(对应数字),以便匹配。

I run it, then at first glance I thought it display correctly.我运行它,乍一看我认为它显示正确。 It does, but there are these numbers if you would notice at the end of the first and last name.确实如此,但如果您注意到名字和姓氏的末尾,就会出现这些数字。 Take a look:看一看:

在此处输入图像描述

The problem is that you use sizeof(fname) and sizeof(lname) (the -1 isn't particularly important here).问题是您使用sizeof(fname)sizeof(lname) (-1 在这里并不是特别重要)。 sizeof() is a compile-time constant that does not correlate to the length of the input. sizeof()是一个编译时常量,与输入的长度无关。

This is a problem is your uninitialized array has something in it that matches your upletters or lowletters array.这是一个问题,因为您未初始化的数组中包含与您的upletterslowletters数组匹配的内容。 Since you check the entire array, your program will print that also.由于您检查了整个数组,因此您的程序也会打印出来。

The solution is to only check the part of the array that has been imputed.解决方案是仅检查已估算的数组部分。 You can do this with strlen() :你可以用strlen()做到这一点:

for(int a = 0; a < strlen(fname); a++){
    //...
}
//...
for(int a = 0; a < strlen(lname); a++){
    // ...
}

Of course, if you are allowed to use std::string (which many C++ classes do not), that is much easier:当然,如果允许您使用std::string (许多 C++ 类不允许使用),那就容易多了:

std::string fname, lname;
//...
for(int a = 0; a < fname.size(); a++){
    //...
}
//...
for(int a = 0; a < lname.size(); a++){
    // ...
}

This is generally preferred because you can't overrun the buffer this way, but you can do what you want/what your professor wants you to do.这通常是首选,因为您不能以这种方式超出缓冲区,但您可以做您想做的/您的教授希望您做的。

When you are working with char arrays you have to use strlen() .当您使用 char arrays 时,您必须使用strlen() If you use std::string it will be automatically resized to fit your input with cin .如果您使用std::string ,它将自动调整大小以适应您的输入cin

Your solution could be simplified by doing a bit of maths.你的解决方案可以通过做一些数学来简化。 No need for those arrays of letters and numbers.不需要那些 arrays 的字母和数字。 Just subtract the value of a char from 'a' or 'A' and add 1 to get the numerical value.只需从 'a' 或 'A' 中减去 char 的值并加 1 即可得到数值。 Also you could do the printing inside a function to avoid duplicated code.您也可以在 function 内进行打印以避免重复代码。

#include <iostream>
#include <string>

using namespace std;

void PrintName(std::string name)
{
    for (size_t a = 0; a < name.length(); a++)
    {
        char letter = name[a];
        if (letter >= 'A' && letter <= 'Z')
            cout << (letter - 'A' + 1) << "\t";
        else if (letter >= 'a' && letter <= 'z')
            cout << (letter - 'a' + 1) << "\t";
    }
}

int main(int argc, char** argv) {

    std::string fname;
    std::string lname;

    cout << "Enter name: ";
    cin >> fname >> lname;

    PrintName(fname);
    PrintName(lname);

    return 0;
}

If you have C++11 or above you can do range based looping instead, eg:如果您有 C++11 或更高版本,则可以进行基于范围的循环,例如:

for (auto letter : lname)

I don't want to give a school assignment to you, but I'd be glad to point out a few helpful hints.我不想给你分配学校作业,但我很乐意指出一些有用的提示。 Starting with: arrays are unnecessary when your array contents are mathematically reproducible:开始: arrays 当您的数组内容在数学上可重现时是不必要的:

  • If ( fname[a]>='a' && fname[a]<='z' ) the matching index in both lowletters & corrNums is fname[a] - 'a'如果( fname[a]>='a' && fname[a]<='z' )lowletters 和 corrNums 中的匹配索引是 fname[a] - 'a'

  • Likewise, if ( fname[a]>='A' && fname[a]<='Z' ) the matching index in upletters & corrNums is fname[a] - 'A'同样,如果 ( fname[a]>='A' && fname[a]<='Z' ) upletters & corrNums 中的匹配索引是 fname[a] - 'A'

  • corrNums[i] = i+1, in every case corrNums[i] = i+1,在任何情况下

  • You are producing the same results regardless of case, so you can use std::tolower to cut your checks in half无论大小写如何,您都会产生相同的结果,因此您可以使用 std::tolower 将支票减半

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

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