字符串管理 C/C++ & 从 txt 文件写入和读取

String Management C/C++ & Writing and Reading From txt File

本文关键字:文件 读取 txt 管理 C++ 字符串      更新时间:2023-10-16

我分别在文件中读取和写入字符串时遇到问题。

目的:要将字符串作为完整句子输入到文本文件中,请从文本文件中读取字符串,并使用函数分隔从元音开始的所有单词,并将它们显示为句子。(句子只需要由字符串中以元音开头的单词组成。

问题:代码按预期工作,但由于我在从 txt 文件中撤回子字符串时使用 getline() 函数从 txt 文件中获取字符串,它包括元音后面的整个文件,而不仅仅是单词。我不明白如何使子字符串只包含单词。

法典:

#include <fstream>
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
string vowels(string a)
{
    int c=sizeof(a);
    string b[c];
    string d;
    static int n;
    for(int i=1;i<=c;i++)
    {
    if (a.find("a")!=-1)
    {
        b[i]=a.substr(a.find("a",n));
        d+=b[i];
        n=a.find("a")+1;
    }
    else if (a.find("e")!=-1)
    {
        b[i]=a.substr(a.find("e",n));
        d+=b[i];
        n=a.find("e")+1;
    }
    else if (a.find("i")!=-1)
    {
        b[i]=a.substr(a.find("i",n));
        d+=b[i];    
        n=a.find("i")+1;
    }
    else if (a.find("o")!=-1)
    {
        b[i]=a.substr(a.find("o",n));
        d+=b[i];
        n=a.find("o")+1;
    }
    else if (a.find("u")!=-1)
    {
        b[i]=a.substr(a.find("u",n));
        d+=b[i];
        n=a.find("u")+1;
    }
    }
    return d;
}
int main()
{
    string input,lne,e; 
    ofstream file("output.txt", ios::app);
    cout<<"Please input text for text file input: ";
    getline(cin,input);
    file << input;
    file.close();
    ifstream myfile("output.txt");
    getline(myfile,lne);
    e=vowels(lne);
    cout<<endl<<"Text inside file reads: ";
    cout<<lne;
    cout<<endl;
    cout<<e<<endl;
    system("pause");
    myfile.close();
    return 0;
}

我没有仔细阅读您的代码,但有几件事很突出:

  1. 查找find_first_of - 它会大大简化您的代码。
  2. sizeof(a)当然不会做你认为它做的事情[除非你认为它给了你std::string类类型的大小 - 这使得它作为一个用例相当奇怪,为什么不使用12或24?
  3. 从技术上讲,find(和find_first_of)在函数找不到您想要的内容时不会返回 -1。它返回 std::string::npos [可能看起来是 -1,但 a) 不能保证是,b) 是未唱的,所以不能是负数]。
  4. 程序只读取一行。
  5. x.substr(n)会给你一串x从位置n - 这是你想要的吗?
  6. 不要重复find,使用p = x.find("X");然后执行x.substr(p)[假设这是你想要的]。

你的代码有各种问题。

int c = sizeof( a );

这是字符串在内存中占用的字节数。而且您当然不想创建这么多字符串的数组,因为这对您想要实现的目标毫无意义。不要这样对自己。你只在循环中复制一个字符串,你只需要一个字符串,你已经有了字符串 d。

要获取字符串的实际大小,您必须调用

str.size()

string.substr(..) 有几个重载,其中一个只接受一个参数,一个索引。这将返回从原始字符串中的该索引开始的子字符串。(从元音开始一直到字符串末尾的字符串)您可能正在寻找的是需要两个参数的重载,即开始索引(单词的开头和单词的结尾)。

字符串输入不会采用您输入的换行符来刷新 cin。然后你把它添加到附加模式下的文件,所以在运行程序几次后,你的文件是一个巨大的单行。你真的打算这样做吗?也许您应该在输入输入后向文件显式添加新行。类似文件<<std::endl;

此外,ifs 中的条件

if (a.find("a")!=-1)

与你接下来要做的事情不匹配,

b[i]=a.substr(a.find("a",n));

然后你使用静态 int,

static int n;

这很糟糕,因为这个函数只能工作一次。幸运的是,static 将其值初始化为零,但您应该始终显式初始化。在您的情况下,您不需要这是静态的。

最后:"所以我不确定要运行多少个循环"当您不知道必须运行多少个循环时,则 for 循环是不够的。您应该使用 while 循环do while

你不应该试图通过猜测来学习C++,因为这就是你正在做的事情。你试图做的比你知道的更多,并犯了一些非常愚蠢的错误。找一本好书来学习,或者至少谷歌一下你正在使用的功能,看看它们的作用以及如何正确使用它们。(即:http://www.cplusplus.com/reference/string/string/substr/)

以下是来自stackoverflow常见问题解答的书籍列表:权威C++书籍指南和列表

最后一件事是关于寻找元音。当你找到一个元音时,你必须确保它在一个单词的开头。然后你想读它,直到单词结束,也就是当你找到一个不属于单词的字符时。(空格,某些标点符号,...这应该标记单词的开头和结尾。