我不能 return C 中的字符串
I can't return a character string in C
你好;
我的程序有问题,需要计算一个IP地址的@host网络。程序的步骤是:
- 在二进制(int)的“网络”变量中添加掩码和 ip
- 将“reseau”变量转换为十进制(在 char[] 中)
- Return main
中的“网络”变量
无论如何,我在第 1 步。为了确保一切正常,我正在尝试 return 包含二进制加法的字符串“reseau”。
问题:很遗憾我做不到。它给我以下错误代码:
returning 'char *' from a function with return type 'char' makes
integer from without a cast [-Wint-conversion] 33. return reseau;
我怀疑这是因为你不能 return 那样的字符标签(根据我的研究),但我无法弄明白。
代码:
#include <stdio.h>
#include <stdio.h>
#include <string.h>
char calcul(char* octet, char* masque);
void main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n", octetB);
printf("octetB 3e valeur : %c\n", octetB[2]);
printf("Adresse réseau : %s\n", calcul(octetB, masqueB));
}
char calcul(char* octet, char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]='1') && (masque[i]='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n", i, reseau[i]);
}
return reseau;
}
所以我很想得到一些帮助来知道我哪里出错了?
为了理解。谢谢 :D
问题是您的函数 calcul()
return 是一个字符数组或指向字符 (char*
) 的指针,尽管您的函数定义说 return 类型是char
。这就是您收到编译错误的原因。
但是你不能 return 数组 reseau
。此变量是本地变量,仅在您的函数内可用。在函数之外 calcul()
这个字符数组不再有效。
您的代码中的下一个问题是 reseau
最后没有 nul 终止。所以你的 printf()
不会像你预期的那样工作。
最后我在你的代码中发现了另一个问题。语句 octet[i]='1'
是一个赋值。在您的情况下,您需要进行比较。您必须将其更改为 octet[i]=='1'
(双等号)。
向上:
我已经考虑了您的意见和解释。现在它可以工作了(使用 malloc 系统)。
感谢您的评论。
这是更新后的代码,供遇到该主题的人使用:
char* calcul(char* octet, char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n", i, reseau[i]);
}
char* result = malloc(strlen(reseau)+1);
strcpy(result, reseau);
return result;
}
您的代码无法编译,因为您在 calcul()
函数 return char
和 returning 字符数组。如果你想 return reseau
字符数组,你可以使用指针来完成。查看下面代码与您的代码的区别,了解如何实现它。
您的代码中也存在一些逻辑问题,例如 reseau
数组中没有结束行,这导致在您想要的字符串之后打印垃圾值。并且您使用一个等于 =
而不是双等于 ==
来比较代码中的相等。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char* calcul(char* octet, char* masque);
int main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n", octetB);
printf("octetB 3e valeur : %c\n", octetB[2]);
printf("Adresse réseau : %s\n", calcul(octetB, masqueB));
}
const char* calcul(char* octet, char* masque){
int i;
char *reseau = malloc(100);
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){//use double equal to compare
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %c\n", i, reseau[i]);
}
reseau[i]= '[=10=]';//add endline
return reseau;
}
使用malloc()
的解决方案的缺点是分配了内存,但释放内存的责任不明确。调用者甚至不需要知道内存是动态分配的(为什么要知道?),并且无法释放它导致内存泄漏。通常释放分配的责任应该是明确的。在这种情况下,这不是一个好的解决方案。
一个简单(但仍然不完善)的解决方案是静态分配返回的字符串:
const char* calcul( const char* octet, const char* masque )
{
static char reseau[33] = "" ;
...
return reseau;
}
但是这有一个不可重入的问题(多线程或递归代码中的一个问题)并且调用者仍然需要了解与使用静态缓冲区相关的限制和问题。返回的指针对于所有调用者都是相同的,这样如果随后调用函数,字符串将被修改。调用者可以复制该字符串,或确保在再次调用该函数之前已完成对它的所有处理。动态内存分配可能更好,但仍然需要调用者了解内部内存管理才能正确使用它。
该解决方案的另一个缺点是返回 const
无法在函数外部执行写访问,因此如果有必要,调用者必须将字符串复制到本地缓冲区。返回一个非常量将是一个非常糟糕的主意 - 您将修改函数内的“隐藏”缓冲区。
更常用和更灵活的习惯用法是让调用者“拥有”缓冲区并将其传递给要填充的函数。这样内存可能是一个数组,或者根据调用者的需要动态分配。在这种情况下,您还可以传递数组的长度,以便函数可以避免溢出调用者的缓冲区:
const char* calcul( const char* octet, const char* masque,
char* reseau, size_t reseau_len )
{
...
for( i = 0;
octet[i] != 0 && masque[i] != 0 && i < reseau_len;
i++)
{
...
}
return reseau;
}
那么函数可以这样调用:
char reseau_buf[sizeof(octetB)] ;
printf( "Adresse réseau : %s\n",
calcul( octetB, masqueB,
reseau_buf, sizeof(reseau_buf) ) ) ;
请注意,最后一个版本也没有对 masque
或 octet
的长度做出任何假设 - 循环在所有输入中较短的一个停止。如果它们不同,那是调用者的错误,函数实现将“优雅地”确定性地失败,因此更容易调试。
除了对作业的解释
上面的 None 似乎正确地解决了您似乎误解了的任务。我希望解决方案看起来像:
#include <stdio.h>
#include <stdint.h>
uint32_t subnet( uint32_t ip, uint32_t mask, char* subnet_str ) ;
int main()
{
uint32_t ip = 0xC0A80001 ; // 192.168.0.1
uint32_t netmask = 0xFFFFFF00 ; // 255.255.255.0
char ipstring[] = "000.000.000.000" ;
printf( "0x%08X : ", subnet(ip, netmask, ipstring) ) ;
printf( "%s\n", ipstring ) ;
}
uint32_t subnet( uint32_t ip, uint32_t mask, char* subnet_str )
{
// Step 1 : apply mask to get subnet
uint32_t network = ...
// Step to: convert network to "xxx.xxx.xxx.xxx" string form
// in subnet_str
...
// Step 3
return network ;
}
输出:
0xC0A80000 : 192.168.1.0
显然对其中任何一个问题的帮助都值得提出一个新问题。但是,远比您已经投入的工作简单。步骤 1 和步骤 2 都可以作为一行代码来实现。
你好;
我的程序有问题,需要计算一个IP地址的@host网络。程序的步骤是:
- 在二进制(int)的“网络”变量中添加掩码和 ip
- 将“reseau”变量转换为十进制(在 char[] 中)
- Return main 中的“网络”变量
无论如何,我在第 1 步。为了确保一切正常,我正在尝试 return 包含二进制加法的字符串“reseau”。
问题:很遗憾我做不到。它给我以下错误代码:
returning 'char *' from a function with return type 'char' makes integer from without a cast [-Wint-conversion] 33. return reseau;
我怀疑这是因为你不能 return 那样的字符标签(根据我的研究),但我无法弄明白。
代码:
#include <stdio.h>
#include <stdio.h>
#include <string.h>
char calcul(char* octet, char* masque);
void main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n", octetB);
printf("octetB 3e valeur : %c\n", octetB[2]);
printf("Adresse réseau : %s\n", calcul(octetB, masqueB));
}
char calcul(char* octet, char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]='1') && (masque[i]='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n", i, reseau[i]);
}
return reseau;
}
所以我很想得到一些帮助来知道我哪里出错了? 为了理解。谢谢 :D
问题是您的函数 calcul()
return 是一个字符数组或指向字符 (char*
) 的指针,尽管您的函数定义说 return 类型是char
。这就是您收到编译错误的原因。
但是你不能 return 数组 reseau
。此变量是本地变量,仅在您的函数内可用。在函数之外 calcul()
这个字符数组不再有效。
您的代码中的下一个问题是 reseau
最后没有 nul 终止。所以你的 printf()
不会像你预期的那样工作。
最后我在你的代码中发现了另一个问题。语句 octet[i]='1'
是一个赋值。在您的情况下,您需要进行比较。您必须将其更改为 octet[i]=='1'
(双等号)。
向上:
我已经考虑了您的意见和解释。现在它可以工作了(使用 malloc 系统)。
感谢您的评论。
这是更新后的代码,供遇到该主题的人使用:
char* calcul(char* octet, char* masque){
int i;
char reseau[100];
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %d\n", i, reseau[i]);
}
char* result = malloc(strlen(reseau)+1);
strcpy(result, reseau);
return result;
}
您的代码无法编译,因为您在 calcul()
函数 return char
和 returning 字符数组。如果你想 return reseau
字符数组,你可以使用指针来完成。查看下面代码与您的代码的区别,了解如何实现它。
您的代码中也存在一些逻辑问题,例如 reseau
数组中没有结束行,这导致在您想要的字符串之后打印垃圾值。并且您使用一个等于 =
而不是双等于 ==
来比较代码中的相等。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char* calcul(char* octet, char* masque);
int main(){
char octetB[]="11000000101010000000000100000111";
char masqueB[]="11111111111111111111111100000000";
printf("octetB : %s\n", octetB);
printf("octetB 3e valeur : %c\n", octetB[2]);
printf("Adresse réseau : %s\n", calcul(octetB, masqueB));
}
const char* calcul(char* octet, char* masque){
int i;
char *reseau = malloc(100);
printf("\n");
printf("octet dans calcul : %s\n", octet);
printf("masque dans calcul : %s\n", masque);
for(i=0; i<32; i++){
if((octet[i]=='1') && (masque[i]=='1')){//use double equal to compare
reseau[i]='1';
} else {
reseau[i]='0';
}
printf("nombre %d : %c\n", i, reseau[i]);
}
reseau[i]= '[=10=]';//add endline
return reseau;
}
使用malloc()
的解决方案的缺点是分配了内存,但释放内存的责任不明确。调用者甚至不需要知道内存是动态分配的(为什么要知道?),并且无法释放它导致内存泄漏。通常释放分配的责任应该是明确的。在这种情况下,这不是一个好的解决方案。
一个简单(但仍然不完善)的解决方案是静态分配返回的字符串:
const char* calcul( const char* octet, const char* masque )
{
static char reseau[33] = "" ;
...
return reseau;
}
但是这有一个不可重入的问题(多线程或递归代码中的一个问题)并且调用者仍然需要了解与使用静态缓冲区相关的限制和问题。返回的指针对于所有调用者都是相同的,这样如果随后调用函数,字符串将被修改。调用者可以复制该字符串,或确保在再次调用该函数之前已完成对它的所有处理。动态内存分配可能更好,但仍然需要调用者了解内部内存管理才能正确使用它。
该解决方案的另一个缺点是返回 const
无法在函数外部执行写访问,因此如果有必要,调用者必须将字符串复制到本地缓冲区。返回一个非常量将是一个非常糟糕的主意 - 您将修改函数内的“隐藏”缓冲区。
更常用和更灵活的习惯用法是让调用者“拥有”缓冲区并将其传递给要填充的函数。这样内存可能是一个数组,或者根据调用者的需要动态分配。在这种情况下,您还可以传递数组的长度,以便函数可以避免溢出调用者的缓冲区:
const char* calcul( const char* octet, const char* masque,
char* reseau, size_t reseau_len )
{
...
for( i = 0;
octet[i] != 0 && masque[i] != 0 && i < reseau_len;
i++)
{
...
}
return reseau;
}
那么函数可以这样调用:
char reseau_buf[sizeof(octetB)] ;
printf( "Adresse réseau : %s\n",
calcul( octetB, masqueB,
reseau_buf, sizeof(reseau_buf) ) ) ;
请注意,最后一个版本也没有对 masque
或 octet
的长度做出任何假设 - 循环在所有输入中较短的一个停止。如果它们不同,那是调用者的错误,函数实现将“优雅地”确定性地失败,因此更容易调试。
除了对作业的解释
上面的None 似乎正确地解决了您似乎误解了的任务。我希望解决方案看起来像:
#include <stdio.h>
#include <stdint.h>
uint32_t subnet( uint32_t ip, uint32_t mask, char* subnet_str ) ;
int main()
{
uint32_t ip = 0xC0A80001 ; // 192.168.0.1
uint32_t netmask = 0xFFFFFF00 ; // 255.255.255.0
char ipstring[] = "000.000.000.000" ;
printf( "0x%08X : ", subnet(ip, netmask, ipstring) ) ;
printf( "%s\n", ipstring ) ;
}
uint32_t subnet( uint32_t ip, uint32_t mask, char* subnet_str )
{
// Step 1 : apply mask to get subnet
uint32_t network = ...
// Step to: convert network to "xxx.xxx.xxx.xxx" string form
// in subnet_str
...
// Step 3
return network ;
}
输出:
0xC0A80000 : 192.168.1.0
显然对其中任何一个问题的帮助都值得提出一个新问题。但是,远比您已经投入的工作简单。步骤 1 和步骤 2 都可以作为一行代码来实现。