C++ Pascal 字符串错误。我在代码中找不到错误

Posted

技术标签:

【中文标题】C++ Pascal 字符串错误。我在代码中找不到错误【英文标题】:C++ Pascal Strings errors. I cannot find the error in my code 【发布时间】:2016-04-11 23:41:06 【问题描述】:

下面是我的代码,然后是错误消息。我将不胜感激任何帮助。谢谢你。作业如下:

修改提供的 String 类以在内部存储 Pascal 字符串,这些字符串是字符数组,以字符串中的多个字符开头,后跟这些字符,no 终止空字符。那就是:

str 应该包含一个 Pascal 字符串。 应该包括在您的 Pascal 字符串实验室中创建的构造函数。 还应包含普通的 C 字符串构造函数,并且必须转换为 Pascal 字符串。 c_str 函数必须转换回 C 字符串以向用户提供 C 字符串。在这个函数中为字符串分配内存是可以的。 考虑到内部字符串格式的更改,所有其他函数必须正确执行。 您可以在内部将 C 字符串与 Pascal 字符串一起存储。
帕斯卡.cpp
// Pascal Main cpp


#include <iostream>
#include <algorithm>
#include "Pascal.h"
#include <exception>
using namespace std;
// Default constructor
String::String() 
    arr = new char[1];
    arr[0] = '\0';
    len = 0;


// Constructor. Converts a C-string to a String object
String::String(const char *s) 
    len = strlen(s);
    arr = new char[len + 1];
    std::copy(s, s + len + 1, arr);


// Copy constructor.
String::String(const String &obj) 
    len = obj.len;
    arr = new char[len + 1];
    std::copy(obj.arr, obj.arr + len + 1, arr);


// Move constructor.
String::String(String &&obj) 
    len = obj.len;
    arr = obj.arr;
    obj.arr = nullptr;


String::String(const char *str, bool pascal) 
    judge = pascal;
    if (judge) 
        len = strlen(str) - 1;
        const char *temp = str;
        arr = new char[len + 1];
        arr[0] = len + '0';
        for (int i = 1; i <= len; i++) 
            arr[i] = temp[i];
        

    
    else 
        len = strlen(str);
        arr = new char[len + 1];
        std::copy(str, str + len + 1, arr);
    


// Destructor
String::~String() 
    if (arr != nullptr)
        delete[] arr;


// Assignment operator
String &String::operator=(const String &rhs) 
    delete[] arr;
    len = rhs.len;
    arr = new char[len + 1];
    std::copy(rhs.arr, rhs.arr + len + 1, arr);
    return *this;


// Move assignment operator
String &String::operator=(String &&rhs) 
    delete[] arr;
    len = rhs.len;
    arr = rhs.arr;
    rhs.arr = nullptr;
    return *this;



// Mutator operator[]
char &String::operator[](int index) 
    // check whether the index is within bounds
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];


// Accessor operator[]
char String::operator[](int index) const 
    // check whether the index is within bounds
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];


// Get the length (number of characters) of a String object
int String::length() const 
    return len;


bool operator==(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return strcmp(lhs.arr, rhs.arr) == 0;


bool operator<(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return strcmp(lhs.arr, rhs.arr) < 0;


// Friend functions for > comparison
bool operator>(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return rhs < lhs;


// Friend functions for <= comparison
bool operator<=(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return !(rhs < lhs);


// Friend functions for >= comparison
bool operator>=(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return !(lhs  < rhs);


// Friend functions for != comparison
bool operator!=(const String &lhs, const String &rhs) 
    if (lhs.judge != rhs.judge) 
        cout << "can't compare";
    
    return !(lhs == rhs);


//  Friend function for string concatination
String operator+(const String &lhs, const String &rhs) 
    if (lhs.judge == rhs.judge && lhs.judge == false) 
        int strLength = lhs.len + rhs.len + 1;
        char *tmpStr = new char[strLength];
        for (auto i = 0; i < lhs.len; ++i)
            tmpStr[i] = lhs.arr[i];
        for (auto i = 0; i <= rhs.len; ++i)
            tmpStr[lhs.len + i] = rhs.arr[i];
        String retStr(tmpStr);
        delete[] tmpStr;
        return retStr;
    
    else if (lhs.judge == rhs.judge && lhs.judge == true) 
        int strLength = lhs.len + rhs.len + 1;
        char *tmp = new char[strLength];
        for (auto i = 1; i <= lhs.len; ++i)
            tmp[i] = lhs.arr[i];
        for (auto i = 1; i <= rhs.len; ++i)
            tmp[lhs.len + i] = rhs.arr[i];
        tmp[0] = (lhs.len + rhs.len) + '0';
        String retStr(tmp);
        delete[] tmp;
        return retStr;
    
    else 
        return String("can't do that");
    


// Return C style character string
const char* String::c_str() const 
    return arr;


//  Friend function for output
std::ostream& operator<<(std::ostream &out, const String &obj) 
    return out << obj.c_str();

帕斯卡.h
// Pascal Header File

#pragma once
#ifndef __MYSTRING_H__
#define __MYSTRING_H__

#include <iostream>

class String 
public:
    // Usage: String aStringObj; or String aStringObj();
    String();

    // Constructor. Converts a char* object to a String  object
    // Usage: String aStringObj("hello"); or String aStringObj = "hello";
    String(const char *s);

    // Copy and move constructors.
    // Usage: String aStringObject(anotherStringObj); or
    // String aStringObject = anotherStringObj;
    String(const String &s);
    String(const char *str, bool pascal);
    String(String&& obj);

    // Destructor
    ~String();

    // Assignment operator
    // Usage: aStringObject = anotherStringObj; or
    // aStringObject.operator=(anotherStringObj);
    String &operator=(const String &rhsObject);
    String& operator=(String&& rhs);

    // Mutator operator[]
    // Usage: aStringObject[1] = ’M’;
    char &operator[] (int index);

    // Accessor operator[]
    // Usage: char ch = aStringObject[1];
    char operator[] (int index) const;

    // Get the length (number of characters) of a String object
    // Usage: int len = aStringObject.Length();
    int length() const;

    // Friend functions for == comparison
    // Usage: if (aStringObject == anotherStringObj) ... or
    //        if (aStringObject == "hello") ... or
    //        if ("hello" == aStringObj) ... or
    friend bool operator==(const String &lhsObject, const String &rhsObject);

    // The other five comparison operators
    // !=, <, >, <=, >= are similarly handled as in line 13.

    friend bool operator<(const String &lhsObject, const String &rhsObject);
    friend bool operator>(const String &lhsObject, const String &rhsObject);
    friend bool operator<=(const String &lhsObject, const String &rhsObject);
    friend bool operator>=(const String &lhsObject, const String &rhsObject);
    friend bool operator!=(const String &lhsObject, const String &rhsObject);

    // Friend function for string concatenation
    // Usage: StringOne = StringTwo + StringThree  or
    //        StringOne = "hello" + StringTwo  or
    //        StringOne = StringTwo + "hello"
    friend String operator+(const String &lhs, const String &rhs);

    // Return C style character string
    // Usage: const char *str = aStringObj.C_str();
    const char *c_str() const;

    // Friend function for output
    // Usage: cout << aStringObj;
    friend std::ostream &operator<<(std::ostream &out, const String &obj);

private:
    // arr implements the String object as a dynamic array
    char *arr;

    // len keeps track of the length
    int len;

    // judge weather the String is a c_string or a pascal_string
    bool judge;
;

#endif

编译时出现以下警告和错误:

严重性代码 描述 项目文件行抑制状态 警告 C4996 'std::_Copy_impl':带有可能不安全的参数的函数调用 - 此调用依赖于调用者检查传递的值是否正确。要禁用此警告,请使用 -D_SCL_SECURE_NO_WARNINGS。请参阅有关如何使用 Visual C++ 'Checked Iterators' Pascal Assignment c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility 2229 的文档 严重性代码 描述 项目文件行抑制状态 错误 LNK1120 1 未解决的外部 Pascal 分配 C:\Users\Danielle\Documents\Visual Studio 2015\Projects\Pascal Assignment\Debug\Pascal Assignment.exe 1 严重性代码 描述 项目文件行抑制状态 错误 LNK2019 未解析的外部符号 _main 在函数“int __cdecl invoke_main(void)”(?invoke_main@@YAHXZ) Pascal 分配 C:\Users\Danielle\Documents\Visual Studio 2015\Projects\Pascal Assignment\MSVCRTD.lib(exe_main.对象)1

【问题讨论】:

我确实喜欢不可读的图像。请剪切'n'粘贴相关文字 我看得到,你看不到吗?如果您单击图像,它会显示一个更大的版本。我可以再试一次。 What is an undefined reference/unresolved external symbol error and how do I fix it?的可能重复 @danie 它不在您发布的代码中,您需要一个签名为int main(int argc, char** argv)的函数 @danie - 让我们的生活变得轻松是一种礼貌。您可以剪切'n'粘贴错误。我们中的一些人使用移动设备 【参考方案1】:

缺少 main 函数是因为您还没有定义一个函数,并且您正在编译为一个程序。这应该是一个库项目,或者应该有一个main 函数。 代码末尾的#endif 表示这是一个没有显示开头的标题。如果是这样,那么 y您需要一个单独的 .cpp 文件(例如)将您的 main 放入。


在其他新闻中:

包含两个连续下划线的标识符,如 __MYSTRING_H__,是 保留 实现的,因此可能会导致问题。此外,保留以下划线后跟大写字母开头的标识符。使用例如只是MYSTRING_H。但是:

当您使用#pragma once 时,您不需要包含保护符号。

我还没有真正研究过代码,但除非你使用像 &lt;&lt; 这样的操作,或者例如endl,在标题中,那么您不需要在标题中包含整个&lt;iostream&gt;。包含&lt;iosfwd&gt; 就足够了。这就是它的用途:精益且仅意味着相关类型的声明。您仍然需要在使用标准流的地方包含&lt;iostream&gt;,即在您的实现文件中。但此费用不计入客户端代码。

【讨论】:

我确实有一个 main.cpp 文件。我只是没有显示它,因为它除了包含头文件之外什么都没有。 好的,只需添加int main(),即最短的main 在这个答案中重新删除文本:在研究了代码后,我发现它既是一个实现文件又是一个头文件,连接在一起。我编辑了问题以将它们分开并添加文件名标题。然后添加删除线。

以上是关于C++ Pascal 字符串错误。我在代码中找不到错误的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio C++ 2010 中找不到或打开 PDB 文件

在 Visual Studio C++ 2010 中找不到或打开 PDB 文件

获取 `favicon.ico` 错误,但在代码中找不到

我在 Qt 设计器文件->新建中找不到 C++ 项目

发生了错误。 : 在应用程序配置文件中找不到名为“EmployeeDBEntities”的连接字符串

由于在 Bjarne Stroustrup“使用 c++ 的编程和实践”中找不到符号而导致的链接错误