首页 > 解决方案 > Sprintf_s 给了我奇怪的盒子而不是字符串

问题描述

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "resource.h"


char* getString(HWND hwnd,int dlgItem) 
{
    int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
    if (len > 0)
    {
        TCHAR szBuffer[128] = { 0 };
        int s = GetDlgItemText(hwnd, dlgItem, szBuffer, len + 1);
        return szBuffer;
    }
    return "";
}

int getInt(HWND hwnd, int dlgItem)
{
    int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
    if (len > 0)
    {
        BOOL bsuccess;
        int Number = GetDlgItemInt(hwnd, dlgItem, &bsuccess, FALSE);
        return Number;
    }
    return 0;
}

char* _personRecord(HWND hwnd)
{
    int nameLength = GetWindowTextLength(GetDlgItem(hwnd, txtName)) + 1;
    int addressLength = GetWindowTextLength(GetDlgItem(hwnd, txtAddress)) + 1;
    int phoneLength = GetWindowTextLength(GetDlgItem(hwnd, txtPhone)) + 1;
    int emailLength = GetWindowTextLength(GetDlgItem(hwnd, txtEmail)) + 1;

    char* name = malloc(nameLength);
    name = getString(hwnd, txtName);
    int age = getInt(hwnd, txtAge);
    char* address = malloc(addressLength);
    address = getString(hwnd, txtAddress);
    int zip = getInt(hwnd, txtZip);
    char* phone= malloc(phoneLength);
    phone = getString(hwnd, txtPhone);
    char* email = malloc(emailLength);
    email = getString(hwnd, txtEmail);
    int length = nameLength + addressLength + phoneLength + emailLength + age + zip;
    char* personRecord = malloc(length);

    sprintf_s(personRecord , length, "Name: %s\nAge: %d\nAddress: %s\nZip: %d\nPhone: %s\nEmail: %s\n", name, age, address, zip, phone, email);

    OutputDebugString("\nStart*********\n");
    OutputDebugString(personRecord);
    OutputDebugString("\nEnd**********\n");
    return personRecord;

    free(name);
    free(address);
    free(phone);
    free(email);
    free(personRecord);
}

void saveFile(char* record)
{
    FILE* fp = NULL;
    if(fopen_s(&fp,"contacts.txt", "a") == 0)
    {
        fprintf(fp, "\n");
        fprintf(fp, record);
        fclose(fp);
    }
    else
    {
        OutputDebugString("Op failed");
    }
}

//Works 100 percent.
void clear(HWND hwnd)
{
    SetDlgItemText(hwnd, txtName, "");
    SetDlgItemText(hwnd, txtAge, "");
    SetDlgItemText(hwnd, txtAddress, "");
    SetDlgItemText(hwnd, txtZip, "");
    SetDlgItemText(hwnd, txtPhone, "");
    SetDlgItemText(hwnd, txtEmail, "");
}


BOOL CALLBACK EventHandler(HWND holdWindow, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
    case WM_INITDIALOG:
        break;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case btnSave:
            saveFile(_personRecord(holdWindow));
            clear(holdWindow);
            break;
        case btnLoad:
            //print all records to console
            break;
        case btnClose:
            EndDialog(holdWindow, 0);
        }
        break;
    case WM_CLOSE:
        EndDialog(holdWindow, 0);
        break;
    default:
        return FALSE;
    }
    return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    return DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, EventHandler);
}

第一次真正破解一个真正做任何值得注意的 C 程序。我确定我在内存管理方面做错了很多,但我是新手,所以请放轻松。就我的问题而言,当我将这些字符串打印出来并将它们保存到文件时,sprintf 会将它们变成框。我认为可能是我的 getString 方法导致了这个问题,但是如果我在调用它之后打印出一个变量,它在调试中可以正常工作。我已经尝试过多次调整我分配 personRecord 的方式,包括将其设为静态和 NULL。我也试过单独打印它们。在这一点上,我完全不知所措。

标签: cwindowswinapimemory-managementwin32gui

解决方案


char* szBuffer[1024] = { 0 }; 

TCHAR 是错误的类型,并且 128 没有足够的内存来正确保存字符串。我调整了可以使用的内存量,它解决了这个问题。我认为正确的答案是将数据分配到我从窗口中获取的字符串的长度,但我不确定。感谢所有发帖的人。

char* getString(HWND hwnd,int dlgItem) 
{
    int len = GetWindowTextLength(GetDlgItem(hwnd, dlgItem));
    if (len > 0)
    {
        char* record = malloc(len * sizeof *record + 1);
        int s = GetDlgItemText(hwnd, dlgItem, record, len + 1);
        return record;
        free(record);
    }
    return "";
}

推荐阅读