在双指针数组中将字符串更改为上层
Changing strings to upper within a double pointer array
我需要转换命令行给出的参数,例如:$ myprogram hello world
并且单词需要大写。除了访问双指针数组以使用 toupper()
进行更改之外,我可以做任何事情
static char **duplicateArgs(int argc, char **argv)
{
char **copy = malloc(argc * sizeof (*argv));
if(copy == NULL){
perror("malloc returned NULL");
exit(1);
}
int i;
for(i = 0; i<argc; i++){
copy[i] = argv[i];
}
char **temp;
temp = ©[1];
*temp = toupper(copy[1]);
return copy;
}
从toupper()
的man page函数原型是
int toupper(int c);
在您的代码中,参数 copy[1]
不是 int
值。
相反,您想要的是检查每个元素,如果它们是小写,则将它们转换为大写。伪代码看起来像
for(i = 0; i<argc; i++){
copy[i] = malloc(strlen(argv[i])+ 1); //allocate memory
for (j = 1; j < argc; j++)
for (i = 0; i < strlen(argv[j]); i++)
{
if (islower(argv[j][i])) //check if it is lower case
copy[j-1][i] = toupper(argv[j][i]);
else
copy[j-1][i] = argv[j][i]; //do not convert
}
*temp = toupper(copy[1]);
toupper
转换单个字符,如果要转换整个字符串:
char *temp = copy[1]; /* You don't need a double pointer */
size_t len = strlen(temp);
for (size_t i = 0; i < len; i++) {
temp[i] = toupper(temp[i]);
}
我假设传递给函数的参数 char **argv
是直接从 main 传递的,因此它表示指向指向每个命令行参数的指针数组开头的指针。
argc
表示命令行参数个数。
在您的函数内部,您创建了一个新缓冲区,然后将 argv 的内容复制到其中。因此,您正在创建指向命令行参数的指针数组的副本,而不是命令行参数字符串本身。
我猜您打算复制字符串,而不是指向字符串的指针(这样做有什么意义?)。我建议你查看函数 strdup and/or strncpy 来复制实际的字符串。
这也解释了 'toupper' 没有像您预期的那样工作 - 您不是向它传递单个字符,而是向它传递一个指向以空字符结尾的字符串的指针。
您 运行 使用 toupper()
函数时出错,因为您试图传入一个字符串而不是单个字母。以下是描述该函数的手册页的摘录:
DESCRIPTION
The toupper() function converts a lower-case letter to the corresponding
upper-case letter. The argument must be representable as an unsigned
char or the value of EOF.
您有一个指向指针的指针,您可以将其可视化为类似这样的东西。在 C 中,字符串只是 char
的数组,因此您需要取消引用两次才能获取第二级数组(单个字母)中的数据。每次添加一个 *
都可以认为是去掉了一层指针。您可以将 *
运算符视为 &
运算符的逆运算。
这一行是你的问题行
temp = ©[1];
试试这个
//This is a pointer to an individual string
char *temp = copy[1];
//Keep going while there are letters in the string
while(*temp != NULL) {
//convert the letter
toupper(*temp);
//Advance the pointer a letter
temp++;
}
考虑这个例子:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
static char **duplicateArgs(int argc, char **argv)
{
char **copy = NULL;
// allocate memry for pointers to new lines
copy = (char **)malloc(sizeof(char *) * argc);
int line, chr;
for(line = 0; line < argc; line++)
{
// allocate memory for new line
copy[line] = (char *)malloc(sizeof(char) * (strlen(argv[line]) + 1));
// copy with changes
for(chr = 0; chr <= strlen(argv[line]); chr++)
{
copy[line][chr] = toupper(argv[line][chr]);
}
}
return copy;
}
int main(int argc, char * argv[])
{
char ** strs;
int i;
strs = duplicateArgs(argc, argv);
for(i = 0; i < argc; i++)
{
printf("%s\n", strs[i]);
}
return 0;
}
编辑:
您还可以决定使用 argv[0](可执行文件的名称)并根据需要更改代码。还可以添加对 malloc
结果的检查,以及其他改进...如果您需要 :-)
我需要转换命令行给出的参数,例如:$ myprogram hello world
并且单词需要大写。除了访问双指针数组以使用 toupper()
进行更改之外,我可以做任何事情static char **duplicateArgs(int argc, char **argv)
{
char **copy = malloc(argc * sizeof (*argv));
if(copy == NULL){
perror("malloc returned NULL");
exit(1);
}
int i;
for(i = 0; i<argc; i++){
copy[i] = argv[i];
}
char **temp;
temp = ©[1];
*temp = toupper(copy[1]);
return copy;
}
从toupper()
的man page函数原型是
int toupper(int c);
在您的代码中,参数 copy[1]
不是 int
值。
相反,您想要的是检查每个元素,如果它们是小写,则将它们转换为大写。伪代码看起来像
for(i = 0; i<argc; i++){
copy[i] = malloc(strlen(argv[i])+ 1); //allocate memory
for (j = 1; j < argc; j++)
for (i = 0; i < strlen(argv[j]); i++)
{
if (islower(argv[j][i])) //check if it is lower case
copy[j-1][i] = toupper(argv[j][i]);
else
copy[j-1][i] = argv[j][i]; //do not convert
}
*temp = toupper(copy[1]);
toupper
转换单个字符,如果要转换整个字符串:
char *temp = copy[1]; /* You don't need a double pointer */
size_t len = strlen(temp);
for (size_t i = 0; i < len; i++) {
temp[i] = toupper(temp[i]);
}
我假设传递给函数的参数 char **argv
是直接从 main 传递的,因此它表示指向指向每个命令行参数的指针数组开头的指针。
argc
表示命令行参数个数。
在您的函数内部,您创建了一个新缓冲区,然后将 argv 的内容复制到其中。因此,您正在创建指向命令行参数的指针数组的副本,而不是命令行参数字符串本身。
我猜您打算复制字符串,而不是指向字符串的指针(这样做有什么意义?)。我建议你查看函数 strdup and/or strncpy 来复制实际的字符串。
这也解释了 'toupper' 没有像您预期的那样工作 - 您不是向它传递单个字符,而是向它传递一个指向以空字符结尾的字符串的指针。
您 运行 使用 toupper()
函数时出错,因为您试图传入一个字符串而不是单个字母。以下是描述该函数的手册页的摘录:
DESCRIPTION
The toupper() function converts a lower-case letter to the corresponding
upper-case letter. The argument must be representable as an unsigned
char or the value of EOF.
您有一个指向指针的指针,您可以将其可视化为类似这样的东西。在 C 中,字符串只是 char
的数组,因此您需要取消引用两次才能获取第二级数组(单个字母)中的数据。每次添加一个 *
都可以认为是去掉了一层指针。您可以将 *
运算符视为 &
运算符的逆运算。
这一行是你的问题行
temp = ©[1];
试试这个
//This is a pointer to an individual string
char *temp = copy[1];
//Keep going while there are letters in the string
while(*temp != NULL) {
//convert the letter
toupper(*temp);
//Advance the pointer a letter
temp++;
}
考虑这个例子:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
static char **duplicateArgs(int argc, char **argv)
{
char **copy = NULL;
// allocate memry for pointers to new lines
copy = (char **)malloc(sizeof(char *) * argc);
int line, chr;
for(line = 0; line < argc; line++)
{
// allocate memory for new line
copy[line] = (char *)malloc(sizeof(char) * (strlen(argv[line]) + 1));
// copy with changes
for(chr = 0; chr <= strlen(argv[line]); chr++)
{
copy[line][chr] = toupper(argv[line][chr]);
}
}
return copy;
}
int main(int argc, char * argv[])
{
char ** strs;
int i;
strs = duplicateArgs(argc, argv);
for(i = 0; i < argc; i++)
{
printf("%s\n", strs[i]);
}
return 0;
}
编辑:
您还可以决定使用 argv[0](可执行文件的名称)并根据需要更改代码。还可以添加对 malloc
结果的检查,以及其他改进...如果您需要 :-)