MinGW中超过15个字符的字符串问题[关闭]

Posted

技术标签:

【中文标题】MinGW中超过15个字符的字符串问题[关闭]【英文标题】:Problem with strings longer than 15 characters in MinGW [closed] 【发布时间】:2018-12-27 10:24:58 【问题描述】:

问题描述

std::getline() 函数有问题。我是这样使用的:

std::fstream f; // opened in read in text mode
std::string name;
std::getline(f, name);

对于包含短文本的文件,一切都很好,f.e.:

example text

但是当我尝试阅读更长的内容时,f.e.:

example text in file longer than 15

我得到(编译运行后):

delete: invalid pointer 00FD7A48 (0040CD22)
*** Checking for memory corruption: START
*** Checking for memory corruption: 0 FOUND

文件

main.cpp:

#include <string>
#include <cstring>
#include "plik.h"
#include "prowadzacy.h"

using namesapce std;

int main(int argc, char** argv) 
    if (argc == 3 && !strcmp(argv[1], "-f")) 
        Prowadzacy* baza = nullptr;
        string fn(argv[2]);
        czytajZPliku(fn, baza);
    

prowadzacy.h:

#include "przedmiot.h"

struct Prowadzacy 
    std::string imie;
    std::string nazwisko;

    Przedmiot* przedmiot = nullptr;

    Prowadzacy* next = nullptr;
;

przedmiot.h:

struct Przedmiot 
    std::string nazwa;
    enum Rodzaj 
        WYKLAD, CWICZENIA, LABORATORIUM, PROJEKT, SEMINARIUM
     rodzaj;
    enum DzienTygodnia 
        PONIEDZIALEK, WTOREK, SRODA, CZWARTEK, PIATEK, SOBOTA, NIEDZIELA
     dzien_tygodnia;
    int godzina;
    int czas_trwania;
    std::string miejsce;

    Przedmiot* next = nullptr;
;

plik.h:

#include <fstream>
#include <iostream>
#include "prowadzacy.h"
#include "przedmiot.h"

bool zapiszDoPliku (const std::string, Prowadzacy*&);
bool czytajZPliku (const std::string, Prowadzacy*&);

plik.cpp:

using namespace std;

bool czytajZPliku (const string fn, Prowadzacy*& baza) 
    fstream f;
    f.open(fn, ios::in);
    if (f) 
        string typ;
        Prowadzacy* p = baza;

        while (getline(f, typ, ' ')) 
            cout << typ << endl;
            if (typ.find("[prowadzacy]") != string::npos) 
                string imie, nazwisko;
                while (p != nullptr)
                    p = p->next;
                getline(f, imie, ',');
                getline(f, nazwisko);
                dodajProwadzacego(imie, nazwisko, baza);
             else if (typ.find("[przedmiot]") != string::npos) 
                string nazwa;
                getline(f, nazwa);
            
        
        f.close();
        return true;
    
    return false;

包含我需要获取的数据的文件:

[prowadzacy] Jan,Nowak
[przedmiot] Informatyka w Technologii

我使用 Makefile 和 MinGW。使用标志编译-std=c++14 -O3 -g -pedantic-errors

问题更新

我编写简单的新程序:

#include <string>
#include <iostream>
int main () 
    std::string str = "123456789012345";
    std::cout << str << std::endl;
    return 0;

编译和运行这些我没有问题。但是当我将其代码更改为:

#include <string>
#include <iostream>
int main () 
    std::string str = "1234567890123456";
    std::cout << str << std::endl;
    return 0;

我明白了:

1234567890123456
delete: invalid pointer 00F27F48 (004157B0)
*** Checking for memory corruption: START
*** Checking for memory corruption: 0 FOUND

在 Visual Studio 中一切正常。为什么在 MinGW 中它不起作用?

编译: g++ -std=c++14 -pedantic-errors -Wall -Wextra -O3 -g -pedantic-errors -o main main.cpp

更新:我也在 Linux 上对此进行了测试。在 Linux 上一切都很好。问题仅出现在 Windows 上的 MinGW 中。

解决方案

在编译命令中添加-std=c++14 可以解决这个问题。

【问题讨论】:

C++ 中的字符串是std::string。使用它而不是 C 风格的字符串。 我想使用std::string,但这让我错误了我的描述。 请改进edit你的问题以显示一些minimal reproducible example 再次编辑以提供minimal reproducible example(这意味着带有main完整程序,并显示编译命令它和输入文件示例)。可能你有一些错误其他地方 请改进您的代码以完整,并请在您的代码中使用看起来像英文的名称(这有助于理解您想要做什么)。还请告诉我们您使用调试器所理解的内容。顺便说一句,您在调试程序时最好使用-Og-O0 而不是-O3 进行编译 【参考方案1】:

使用std::string相关的std::getline函数(来自&lt;string&gt;标准头)例如

std::string linstr;
std::getline (std::cin, linstr);

避免使用原始的char* 缓冲区。

还要注意 UTF-8 is used everywhere 在 2018 年(您可以期望您的用户将他们的系统配置为使用 UTF-8;或者您应该处理其他 character encodings)。

最后,你的程序可能在其他地方有(并且可能有)一些错误(例如一些undefined behavior)。阅读How to debug small programs。编译所有警告和调试信息(所以g++ -Wall -Wextra -g 和GCC)。使用gdb debugger 和valgrind。

更新

当我将其代码更改为:

#include <string>
#include <iostream>
int main () 
   std::string str = "1234567890123456";
   std::cout << str << std::endl;
   return 0;

我得到无效指针

可能,你的电脑出了点问题(上面的代码是完全合法的 C++11)。我猜你错误地安装了 MinGW,或者一些错误的设置(例如PATH 或其他)或配置。获得更多帮助;你需要解释更多。

仅供参考,您的最后一个代码(当然)在我的 Linux 发行版(Debian/Sid、GCC 8.2)上运行良好。我建议安装和使用一些 Linux 发行版,特别是因为它对开发人员更友好(并且提供了valgrind,这非常对寻找错误很有用)

【讨论】:

我希望你的最后一句话是真的。它不是。大多数 Windows 机器将使用系统定义的代码页,几乎可以肯定不是 UTF-8。 但据我所知,您可以将 Windows 系统配置为使用 UTF-8 你可以。但您的客户可能不会(这是系统配置,而不是程序配置)。 我有:fstream f; string name; getline (f, name); 但我得到内存损坏和无效指针错误。 @blahax2g:在您的问题中显示minimal reproducible example。

以上是关于MinGW中超过15个字符的字符串问题[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

用于 C/C++ 的压缩库能够处理数组中超过 32 位的元素

ffmpeg mingw 编译 8192 字符限制

验证输入字符串 [关闭]

修改server show data三台主机的时间,队列中超过10分钟的数量飙升

我怎样才能把几个字符打印成一个单词[关闭]

致命错误:[关闭]中超过了 30 秒的最大执行时间