在C

时间:2018-11-17 19:07:46

标签: c arrays string pointers strcpy

我在一个小型微型计算机上具有一项功能,可以一次从UART端口发送一个字符。

USART_0_write('x');

这将导致字符x退出串行端口。

我创建了可以正常工作的功能

char source[] = "Test Text.";
for (uint8_t i=0; i < strlen(source); i++){
    USART_0_write(source[i]);
}

我要做的只是简单地动态更新要发送的字符串,而无需为发送的每件事创建不同的数组。

我基本上想做我假设strcpy可以做的事情,但是我无法使该函数正常工作。我有一个使用strcpy进行编译的版本,但是它一定是内存泄漏,因为当我运行它时,芯片上的所有I / O端口都变成了螺丝钉。

strcpy(source,"Different String");

我想做这样的事情,然后再次调用我的第一个函数,并让它在串行端口上打印新的更新字符串。

我了解指针的概念,但是我读过的所有语法解释我都无法理解。我尝试了很多不同的组合,在一切之前和之后都开始了推杆。无论是什么失败。

我读了这个很棒的解释,但是,就像那里的大多数解释一样,当涉及到动态更新字符串时,停止提供实际的代码行实际上使所有代码都在底部运行的事情简直就是捷径: https://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/

谢谢。

其他信息:

((我编辑了我的帖子,并添加了此帖子,因为您必须在“回答”自己的问题之前在下面添加新帖子,并且评论回复部分不允许使用任何格式,并且最多只能包含500个字符)笨)。

我正在尝试通过执行以下操作来创建菜单:

my_string = "Menu item 1";
sendString(my_string); //function to iterate through characters sending them
my_string = "Menu item 2";
sendString(my_string); //function to iterate through characters sending them
my_string = "Menu item 3";
sendString(my_string); //function to iterate through characters sending them

现在,可能有一种方法需要硕士学位。我只是想让这个愚蠢的菜单工作。我实际上是在创建单独的函数,为每行创建一个新的字符数组,这是做错方法的方式,但这是我在与之抗争数小时后唯一能弄清的事情。

4 个答案:

答案 0 :(得分:3)

假设您写的实际上是您尝试过的内容。...

public class Server { private ServerConnectionContainer serverConnectionContainer; public void StartServer() { Console.WriteLine("Please enter the server port and press return:"); string port = Console.ReadLine(); //1. Start listen on a port serverConnectionContainer = ConnectionFactory.CreateServerConnectionContainer(int.Parse(port), false); serverConnectionContainer.ConnectionLost += (a, b, c) => { Console.WriteLine($"{serverConnectionContainer.Count} {b.ToString()} Connection lost {a.IPRemoteEndPoint.Port}. Reason {c.ToString()}"); }; serverConnectionContainer.ConnectionEstablished += connectionEstablished; serverConnectionContainer.AllowUDPConnections = true; serverConnectionContainer.Start(); Console.WriteLine("Server started"); while (true) { } } /// <summary> /// We got a connection. /// </summary> /// <param name="connection">The connection we got. (TCP or UDP)</param> private void connectionEstablished(Connection connection, ConnectionType type) { connection.EnableLogging = true; connection.LogIntoStream(Console.OpenStandardOutput()); Console.WriteLine($"{serverConnectionContainer.Count} {connection.GetType()} connected on port {connection.IPRemoteEndPoint.Port}"); //3. Register packet listeners. connection.RegisterPacketHandler<TrainerRequest>(TrainerRequestReceived, this); } private void TrainerRequestReceived(TrainerRequest req, Connection connection) { Console.WriteLine($"RawDataPacket received. Data: {string.Join(", ", req.Data["pos_ally"])}"); var test = new Dictionary<string, byte[]>(); test.Add("pos_ally", new byte[] { 1, 2, 3, 4 }); connection.Send(new TrainerResponse(test, req)); } } public class Client { public static async Task StartClient() { //Request server IP and port number Console.WriteLine("Please enter the server IP in the format 192.168.0.1 and press return:"); string ip = Console.ReadLine(); Console.WriteLine("Please enter the server port and press return:"); string port = Console.ReadLine(); //Parse the necessary information out of the provided string ConnectionResult connectionResult = ConnectionResult.TCPConnectionNotAlive; //1. Establish a connection to the server. TcpConnection tcpConnection = ConnectionFactory.CreateTcpConnection(ip, int.Parse(port), out connectionResult); //2. Register what happens if we get a connection if (connectionResult == ConnectionResult.Connected) { Console.WriteLine($"{tcpConnection.ToString()} Connection established"); //3. Send a raw data packet request. tcpConnection.KeepAlive = true; while (true) { var test = new Dictionary<string, byte[]>(); test.Add("pos_ally", new byte[] { 5, 6, 7, 8 }); var res = await tcpConnection.SendAsync<TrainerResponse>(new TrainerRequest { Data = test }); Thread.Sleep(100); } } } } 是一个10字节的数组。

source[]长17个字节。

您溢出了"Different String"并破坏了谁知道什么。

答案 1 :(得分:0)

根据您的最新评论,似乎您需要将菜单内容存储在字符串数组中。在C中,这将是char **,例如char **menu;

如果菜单中有3个项目,则可以为菜单分配内存,如下所示:char **menu = (char **)malloc(3 * sizeof(char *));

然后您需要填写菜单中的项目,例如:

menu[0] = (char *)malloc(64 * sizeof(char)); // 64 as an example
menu[1] = (char *)malloc(64 * sizeof(char));
...
strcpy(menu[0], "Item 1");
strcpy(menu[1], "Item 2");
...

,依此类推。 然后,您可以遍历菜单中的三个项目,并将每个项目发送给函数。

for(int i = 0; i < 3; i++) {
    sendString(menu[i]);
}

答案 2 :(得分:0)

这不是一个“答案”,但这是我诱骗stackoverflow允许我发布代码的唯一方法。

void makeMenu(void){
    char **menu = (char **)malloc(3 * sizeof(char *));

    menu[0] = (char *)malloc(64 * sizeof(char)); // 64 as an example
    menu[1] = (char *)malloc(64 * sizeof(char));
    menu[2] = (char *)malloc(64 * sizeof(char));

    strcpy(menu[0], "Welcome to the menu. Make selection:");
    strcpy(menu[1], "1: Turn on light");
    strcpy(menu[1], "2: Turn off light");

}

void sendMenu(**menu){
    for (uint8_t i=0; i < 3; i++){
        sendSingleLine(menu[i]);
    }
}

void sendSingleLine(*string_to_send){
    for (uint8_t i=0; i < strlen(string_to_send); i++){
        USART_0_write(string_to_send[i]);
    }
}

int main(void){
makeMenu();
    sendMenu();
}

^^^尝试过此操作,无法编译。

答案 3 :(得分:0)

感谢大家的帮助,但我没时间了。在此击败。我已经有一段时间了-我已经编写了低级驱动程序和无线电系统等,但是从来不必处理文本。这是他们在第一天Python编码中教的一类东西。大声笑。

这就是我的解决方法。丑陋但行得通。我只调用uart_menu()即可打印。做完了如果我能弄清楚如何将数组发送到该函数而不必每次都重写它,那将很有帮助。

// Output from sublime, which just runs g++ file.cpp && ./file.cpp
fbuff: <0x02> <0x00>
a: 0x0200
stoi(a): 512
b: 
terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoi
[Finished in 0.8s with exit code -6]