从 C 中的函数返回数组到 main
Returning array to main from a function in C
所以基本上我的问题是我想要解压缩函数对“printf("%.*s", repeat, memset(set, c, repeat));”的输出进行签名到数组 dest 和 return 这个 dest 到 main 并将其签名到 Decompressed_Message
这是我的问题的图片
我想要第一个解压版本:和第二个完全一样。
但是,即使我尝试了sprintf()
,我还是无法如愿
这是我的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <ncurses.h>
char* Compression(char* Message, int given_count)
{
int Len;
char count[given_count];
int length = strlen(Message);
char* destination = (char*)malloc(sizeof(char) * (length * 2 + 1));
int i;
int j=0;
int k;
for (i = 0; i < length; i++) {
destination[j++] = Message[i];
Len = 1;
while (i + 1 < length && Message[i] == Message[i + 1]) {
Len++;
i++;
}
sprintf(count, "%d", Len);
for (k = 0; *(count + k); k++, j++) {
destination[j] = count[k];
}
}
destination[j] = '[=10=]';
return destination;
free(destination);
}
char* Decompression(char *Compressed_Message, char* Message){
int length = strlen(Message);
char* dest = (char*)malloc(sizeof(char) * (length * 2 + 1));
while(*Compressed_Message){
int repeat = 0;
char c = *Compressed_Message++;
while(isdigit(*Compressed_Message))
{
repeat = repeat*10 + *Compressed_Message++ - '0';
}
char set[repeat];
printf("%.*s", repeat, memset(set, c, repeat));
memset(dest, c, repeat);
}
dest[length] = '[=10=]';
return dest;
free(dest);
}
int main(void) {
int letters;
float compression_odd;
printf("Data compressor and decompressor\n\n");
FILE *file;
char filename[100]="";
printf("\n\nPlease Enter the name of file: ");
scanf("%99s",filename);
file=fopen(filename,"r");
if(file==NULL){
printf("\n%s File not found.\n\n",filename);
exit(1);
}
fseek(file, 0, SEEK_END);
long count = ftell(file);
fseek(file, 0, SEEK_SET);
char Message[count];
fread(Message, strlen(Message)+1, count, file);
Message[count]='[=10=]';
printf("\nMessage: %s\n", Message);
printf("char number of message: %d\n", strlen(Message));
printf("\nCompressed version: ");
char* Compressed_Message = Compression(Message, count);
printf("\n");
printf("%s", Compressed_Message);
printf("\nchar number of compressed message: %d\n", strlen(Compressed_Message));
compression_odd = ((strlen(Message) - strlen(Compressed_Message)) * 100) / strlen(Message);
if (compression_odd > 100 || compression_odd < 0){
printf("\nCompression ratio is negative Message got longer !\n");
}
else{
printf("\nCompression Ratio is approximately: %.2f", compression_odd);
}
printf("\nDecompressed version: ");
char* Decompressed_Message = Decompression(Compressed_Message, Message);
printf("\nDecompressed version: %s", Decompressed_Message);
/*if (strcmp(Message, DecompressedSize) == 0) {
printf("\nCompression done.\n");
} else {
printf("\nCompression crushed!\n");
}*/
fclose(file);
return 0;
}
你的 Decompression()
功能有几个问题。
char* dest = (char*)malloc(sizeof(char) * (length * 2 + 1));
这没有分配足够大的目的地。例如,如果压缩字符串是 a100
,目标至少需要 101 个字符,但您只会分配 9 个字符。如果不读取所有重复计数,就无法知道目的地需要多大;您应该使用 realloc()
.
逐步增加目的地
在 while
循环中,您不断将每个重复的字符复制到 dest
,而不是在前一个块之后复制它。所以最后,它只包含最后一个重复的字符,而不是全部。
您不需要 set
数组。您可以将 memset()
直接用于 dest
(在添加调整以附加到前一个块之后)并按照您打印的方式打印 set
.
char* Decompression(char *Compressed_Message, char* Message){
int length = 0;
char* dest = NULL;
while(*Compressed_Message){
int repeat = 0;
char c = *Compressed_Message++;
while(isdigit(*Compressed_Message))
{
repeat = repeat*10 + *Compressed_Message++ - '0';
}
dest = realloc(dest, length + repeat + 1);
printf("%.*s", repeat, memset(dest + length, c, repeat));
length += repeat;
}
dest[length] = '[=11=]';
return dest;
}
所以基本上我的问题是我想要解压缩函数对“printf("%.*s", repeat, memset(set, c, repeat));”的输出进行签名到数组 dest 和 return 这个 dest 到 main 并将其签名到 Decompressed_Message
这是我的问题的图片
我想要第一个解压版本:和第二个完全一样。
但是,即使我尝试了sprintf()
,我还是无法如愿
这是我的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <ncurses.h>
char* Compression(char* Message, int given_count)
{
int Len;
char count[given_count];
int length = strlen(Message);
char* destination = (char*)malloc(sizeof(char) * (length * 2 + 1));
int i;
int j=0;
int k;
for (i = 0; i < length; i++) {
destination[j++] = Message[i];
Len = 1;
while (i + 1 < length && Message[i] == Message[i + 1]) {
Len++;
i++;
}
sprintf(count, "%d", Len);
for (k = 0; *(count + k); k++, j++) {
destination[j] = count[k];
}
}
destination[j] = '[=10=]';
return destination;
free(destination);
}
char* Decompression(char *Compressed_Message, char* Message){
int length = strlen(Message);
char* dest = (char*)malloc(sizeof(char) * (length * 2 + 1));
while(*Compressed_Message){
int repeat = 0;
char c = *Compressed_Message++;
while(isdigit(*Compressed_Message))
{
repeat = repeat*10 + *Compressed_Message++ - '0';
}
char set[repeat];
printf("%.*s", repeat, memset(set, c, repeat));
memset(dest, c, repeat);
}
dest[length] = '[=10=]';
return dest;
free(dest);
}
int main(void) {
int letters;
float compression_odd;
printf("Data compressor and decompressor\n\n");
FILE *file;
char filename[100]="";
printf("\n\nPlease Enter the name of file: ");
scanf("%99s",filename);
file=fopen(filename,"r");
if(file==NULL){
printf("\n%s File not found.\n\n",filename);
exit(1);
}
fseek(file, 0, SEEK_END);
long count = ftell(file);
fseek(file, 0, SEEK_SET);
char Message[count];
fread(Message, strlen(Message)+1, count, file);
Message[count]='[=10=]';
printf("\nMessage: %s\n", Message);
printf("char number of message: %d\n", strlen(Message));
printf("\nCompressed version: ");
char* Compressed_Message = Compression(Message, count);
printf("\n");
printf("%s", Compressed_Message);
printf("\nchar number of compressed message: %d\n", strlen(Compressed_Message));
compression_odd = ((strlen(Message) - strlen(Compressed_Message)) * 100) / strlen(Message);
if (compression_odd > 100 || compression_odd < 0){
printf("\nCompression ratio is negative Message got longer !\n");
}
else{
printf("\nCompression Ratio is approximately: %.2f", compression_odd);
}
printf("\nDecompressed version: ");
char* Decompressed_Message = Decompression(Compressed_Message, Message);
printf("\nDecompressed version: %s", Decompressed_Message);
/*if (strcmp(Message, DecompressedSize) == 0) {
printf("\nCompression done.\n");
} else {
printf("\nCompression crushed!\n");
}*/
fclose(file);
return 0;
}
你的 Decompression()
功能有几个问题。
char* dest = (char*)malloc(sizeof(char) * (length * 2 + 1));
这没有分配足够大的目的地。例如,如果压缩字符串是 a100
,目标至少需要 101 个字符,但您只会分配 9 个字符。如果不读取所有重复计数,就无法知道目的地需要多大;您应该使用 realloc()
.
在 while
循环中,您不断将每个重复的字符复制到 dest
,而不是在前一个块之后复制它。所以最后,它只包含最后一个重复的字符,而不是全部。
您不需要 set
数组。您可以将 memset()
直接用于 dest
(在添加调整以附加到前一个块之后)并按照您打印的方式打印 set
.
char* Decompression(char *Compressed_Message, char* Message){
int length = 0;
char* dest = NULL;
while(*Compressed_Message){
int repeat = 0;
char c = *Compressed_Message++;
while(isdigit(*Compressed_Message))
{
repeat = repeat*10 + *Compressed_Message++ - '0';
}
dest = realloc(dest, length + repeat + 1);
printf("%.*s", repeat, memset(dest + length, c, repeat));
length += repeat;
}
dest[length] = '[=11=]';
return dest;
}