给char*一个名份

博客围绕 char* 展开,探讨其作为字符串使用时的问题。通过代码示例展示,char* 在使用中有时被当作指针,如函数返回 NULL 导致运行出错。解决办法是让 char* 名份保持一致,空字符串用 \\ 而非 NULL,避免比较时出错。

给char*一个名分

char* 不停的问自己:我是字符串还是指针?谁能给我一个名份?
先看如下程序:

char* GetName(int nID)
{
 if(nID > 0)
  return "Name";
 else
  return NULL;
}

const char* GetConstName(int nID)
{
 if(nID > 0)
  return "Name";
 else
  return NULL; 
}

一切看起来都是那么的自然,一切看起来都是顺理成章。果真如此吗?试一下下列测试代码:

int main(int argc, char* argv[])
{
//-----------------------------------------
 string strName = GetName(1);
 cout << strName << endl;

 strName = GetName(0);    //run error
 cout << strName << endl;
//---------------------------------
 const string strConstName = GetConstName(1);
 cout << strConstName << endl;

 const string strConstName2 = GetConstName(0); //run error
 cout << strConstName2 << endl;
 
 return 0;
}

一运行就死掉!

char* 可以当作字符串来使用。但在使用的过程中,有时候却又把它用作了指针。正如那两个函数返回

NULL一样。char*明明是个字符串,为什么要返回各NULL?要得到一个空字符串,请使用""吧。把return

NULL;改成return "";就万事大吉了。这样char*前后就一致了。

或许你在埋怨测试代码没有用char*接收返回值。那好,看如下:

char* pStr = GetName(0);
 strcmp(pStr, "");

在比较的的时候,仍然会出错!总不能不让我比较字符串吧!

如何解决?很简单:既然给了char*一个字符串的名份,那就要让它的名份保持一致。不要因为它是个空

字符串就把它用作指针。

详解这段代码EFI_STATUS SearchByName( VOID ) { ShellPrintEx (-1, -1, L"* SearchByName *\n"); EFI_STATUS Status; EFI_GUID Guid; UINTN DataSize; VOID *Data = NULL; UINT32 Attributes; CHAR16 *Name; CHAR16 *Namestr; CHAR16 *InputStr; UINT64 NameSize, NameBufferSize; CHAR16 *AttributesStr; UINTN EventIndex; EFI_INPUT_KEY key; BOOLEAN Found = FALSE; NameBufferSize = sizeof (CHAR16); Name = AllocateZeroPool (NameBufferSize); Status = ShellPromptForResponse( ShellPromptResponseTypeFreeform, L"Please enter variable name:", (VOID**)&InputStr ); if (EFI_ERROR(Status) || InputStr == NULL || StrLen(InputStr) == 0) { ShellPrintEx(-1, -1, L"Error: Invalid variable name input\n"); FreePool(Name); return EFI_INVALID_PARAMETER; } Namestr = InputStr; /*if (!EFI_ERROR(Status) && InputStr != NULL) { ShellPrintEx(-1, -1, L"You entered: %s\n", InputStr); FreePool(InputStr); }*/ while (TRUE) { NameSize = NameBufferSize; Status = gRT->GetNextVariableName (&NameSize, Name, &Guid); if (Status == EFI_NOT_FOUND) { Status = EFI_SUCCESS; break; } if (Status == EFI_BUFFER_TOO_SMALL) { Name = ReallocatePool (NameBufferSize, NameSize, Name); Status = gRT->GetNextVariableName (&NameSize, Name, &Guid); if (Name == NULL) { return EFI_OUT_OF_RESOURCES; } NameBufferSize = NameSize; } if (StrCmp(Name, Namestr) == 0) { Found = TRUE; DataSize = 0; Status = gRT->GetVariable(Name, &Guid, &Attributes, &DataSize, NULL); if (Status == EFI_BUFFER_TOO_SMALL) { Data = AllocatePool(DataSize); if (Data == NULL) { ShellPrintEx(1, -1, L"Warning: Skipping variable %s (out of memory)\n", Name); continue; } //Detect Variable Status Status = gRT->GetVariable(Name, &Guid, &Attributes, &DataSize, Data); AttributesStr = GetAttrStrType (Attributes); //Output Variable INFO (L"--- --- --- --- ---\n"); ShellPrintEx(-1, -1, L"--- Search Variable INFO ---\n"); ShellPrintEx(-1, -1, L"--- Search Variable Name: %s ---\n", Name); ShellPrintEx(-1, -1, L"--- Search Variable Guid: %g ---\n", &Guid); ShellPrintEx(-1, -1, L"--- Search Variable DataSize: %d ---\n", DataSize); ShellPrintEx(-1, -1, L"--- Search Variable Attributes: %s ---\n", AttributesStr); ShellPrintEx(-1, -1, L"--- --- --- --- ---\n"); FreePool(Data); FreePool(AttributesStr); } } } if (!Found) { ShellPrintEx(-1, -1, L"Error: Variable '%s' not found\n", Namestr); Status = EFI_NOT_FOUND; } if (Namestr) FreePool(Namestr); FreePool(Name); ShellPrintEx (-1, -1, L"Press any key to continue...\n"); gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex); gST->ConIn->ReadKeyStroke (gST->ConIn, &key); gST->ConOut->ClearScreen (gST->ConOut); return EFI_SUCCESS; }
最新发布
11-20
`char**` 本质上是一个指向字符指针的指针,通常用于表示字符串数组。由于它本身不具备自动管理内存和动态调整大小的能力,因此给 `char**` 类型添加元素需要手动管理内存。以下是一个示例代码,展示了如何给 `char**` 类型添加元素: ```cpp #include <iostream> #include <cstring> // 给 char** 类型添加元素的函数 char** addElement(char** arr, int& size, const char* newElement) { // 分配新的内存,比原来多一个元素 char** newArr = new char*[size + 1]; // 复制原来的元素到新数组 for (int i = 0; i < size; ++i) { newArr[i] = arr[i]; } // 为新元素分配内存并复制内容 newArr[size] = new char[strlen(newElement) + 1]; strcpy(newArr[size], newElement); // 释放原来的数组 delete[] arr; // 更新数组大小 ++size; return newArr; } int main() { int size = 0; char** arr = nullptr; // 添加元素 arr = addElement(arr, size, "element1"); arr = addElement(arr, size, "element2"); // 打印数组内容 for (int i = 0; i < size; ++i) { std::cout << arr[i] << std::endl; } // 释放内存 for (int i = 0; i < size; ++i) { delete[] arr[i]; } delete[] arr; return 0; } ``` 在上述代码中,定义了一个 `addElement` 函数,用于给 `char**` 类型的数组添加新元素。该函数首先分配一个比原来数组多一个元素的新数组,然后将原来数组的元素复制到新数组中,接着为新元素分配内存并复制内容,最后释放原来的数组并更新数组大小。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值