|
-
July 7th, 2006, 04:04 AM
#1
getting string size at run time
Huy.
I am trying to write a simple program to get the size of two strings at run time. I mean I let the user enter the strings and then I wanna use the sizeof operator to compare the sizes of the two strings.
Heres my code:
Code:
#include <stdio.h>
int main()
{
char string1[],string2[];
size_t size1,size2;
printf("enter string1\n");
gets(string1);
printf("enter string2\n");
gets(string2);
size1 = sizeof(string1);
size2 = sizeof(string2);
printf("the size of string1 is %d\n",size1);
printf("the size of string2 is %d\n",size2);
return 0;
}
and it gives me the following errors:
Compiling...
strng_copy.c
D:\VC++\chap7_pointers\str_copy\strng_copy.c(5) : error C2133: 'string1' : unknown size
D:\VC++\chap7_pointers\str_copy\strng_copy.c(5) : error C2133: 'string2' : unknown size
D:\VC++\chap7_pointers\str_copy\strng_copy.c(11) : warning C4034: sizeof returns 0
D:\VC++\chap7_pointers\str_copy\strng_copy.c(12) : warning C4034: sizeof returns 0
Error executing cl.exe.
strng_copy.obj - 2 error(s), 2 warning(s)
How does one go about telling the compiler that the size(s) would be known only at run time and not at compile time?
Is there any other way to go about it?
Hoping to hear from you
Best Regards,
Aijaz Baig.
-
July 7th, 2006, 04:24 AM
#2
Re: getting string size at run time
Here need to specify a size for your arrays.
Code:
char string1[100],string2[100];
This will return the length of the array, not the the lengt of the string within the array:
Code:
size1 = sizeof(string1);
size2 = sizeof(string2);
To get the length of a string use strlen:
Code:
size1 = strlen(string1);
- petter
-
July 7th, 2006, 04:24 AM
#3
Re: getting string size at run time
Need to use either of these methods;
Code:
char string[30];
or
char *string = new char[a-int-variable];
-
July 7th, 2006, 04:31 AM
#4
Re: getting string size at run time
Why don't you simply use std::string?
-
July 7th, 2006, 05:54 AM
#5
Re: getting string size at run time
do one thing
declare char *str1,*str2;
then
for lengths
int a,b;
a=strlen(str1);
b=strlen(str2);
Try out this
-
July 8th, 2006, 05:19 PM
#6
Re: getting string size at run time
Hi.
I tried the following little code snippet to read a string character by character and store it in contiguous memory locations giving it the feel of an array.
heres my code:
Code:
#include <stdio.h>
#include <conio.h>
int main()
{
char *string1,crrnt_chr;
int chr_cntr=0;
printf("enter string1\n");
do
{
crrnt_chr = *(string1+chr_cntr) = _getch();
chr_cntr++;
}
while (crrnt_chr != '\r');
printf("\nstring1 has %d characters",--chr_cntr);
/*gets(string2);
size1 = strlen(string1);
size2 = strlen(string2);
printf("the size of string1 is %d\n",size1);
printf("the size of string2 is %d\n",size2);*/
return 0;
}
It complies but gives the following warning:
strng_copy.c
D:\VC++\chap7_pointers\str_copy\strng_copy.c(11) : warning C4700: local variable 'string1' used without having been initialized.
The actual problem happens during execution as the screen quits just when im about to enter the first character of my string.
Would someone elaborate please.
Best Regards,
Aijaz.
-
July 8th, 2006, 06:48 PM
#7
Re: getting string size at run time
 Originally Posted by aijazbaig1
Hi.
I tried the following little code snippet to read a string character by character and store it in contiguous memory locations giving it the feel of an array.
Are you writing C code or C++? If it's C++ there is no need to be fooling around with char pointers. Just use std::string.
If it is 'C', there is a lot of things wrong with your code. The major problem is that you are writing to an uninitialized pointer. That's why your program crashes, and that is exactly what the first warning was telling you.
Code:
*(string1+chr_cntr)
string1 is an uninitialized char pointer -- it points to who-knows-where, and you're attempting to assign a character to this random spot in memory.
If you don't know what this means, I suggest you get a good 'C' book (that is, if you are really coding 'C' and not C++). A programming forum really isn't a good place to discuss basics of C and pointers, especially when every 'C' book explains this much better than most here.
Regards,
Paul McKenzie
-
July 8th, 2006, 06:50 PM
#8
Re: getting string size at run time
 Originally Posted by [email protected]
do one thing
declare char *str1,*str2;
then
for lengths
int a,b;
a=strlen(str1);
b=strlen(str2);
Try out this
Yes, try this out, and get a crash. Those pointers are uninitialized.
Regards,
Paul McKenzie
-
July 9th, 2006, 03:11 AM
#9
Re: getting string size at run time
aijazbaig1 : You can't write a correct program with gets... It is an evil function which doesn't check for buffer overflows.
Code:
#include <string.h>
char* ReadWholeLine(FILE* istream) {
/* Returns a newly allocated null-terminated string that the caller must free with free()
Reads a line until a newline character is encountered.
Extract the '\n' from the input stream, but doesn't put it in the buffer.
*/
/* implementation : You could get better performances, using a linked list of buffers instead of realloc'ing the buffer,
but I prefer to keep this code sample simple enough for you
*/
size_t incremental_size=64,current_size=0;
char* buffer=malloc(incremental_size),*pbuffer=buffer;
while(fgets(pbuffer, incremental_size, istream)) {
size_t new_size_read=strlen(pbuffer);
char* new_buffer;
if (pbuffer[new_size_read-1]=='\n') {
char* final_buffer;
pbuffer[new_size_read-1]='\0';
final_buffer=realloc(buffer, current_size+new_size_read);
return final_buffer?final_buffer:buffer;
}
current_size+=new_size_read;
new_buffer= realloc(buffer, current_size+incremental_size);
if (!new_buffer) {free(buffer);return NULL;}
buffer=new_buffer;
pbuffer=buffer+current_size;
}
free(buffer);
return NULL;
}
int main(void) {
char* p;
while(NULL!=(p=ReadWholeLine(stdin))) {
printf("%s\n",p);
free(p);
}
return 0;
}
If your compiler complain "invalid conversion from void* to char*", then you have a C++ compiler... In that case you should use std::string.
Last edited by SuperKoko; July 9th, 2006 at 03:15 AM.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
-
July 9th, 2006, 03:42 AM
#10
Re: getting string size at run time
Hi.
I think the problem with this is that I am using an uninitialized pointer as said above by one of our pals here.
But a pointer variable can be assigned to only three things right, viz. 0, NULL and a valid address in memory.
But in my own case, if I assign the pointer to NULL than i wont be able to dereference the pointer as the NULL pointer could actually be having any type.
So how do I go about getting it fixed?
-
July 9th, 2006, 04:41 AM
#11
Re: getting string size at run time
Hello..
I have come up with the following code which uses a char pointer to allocate memory at run time on the heap.
It then uses these allocated memory locations to store the characters sequentially.
Code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main()
{
char *string1;
int chr_cntr=0,crrnt_chr;
printf("enter string1\n");
string1 = (char *) malloc (500);
do
{
*(string1+chr_cntr) = getchar();
chr_cntr++;
}
while (string1[chr_cntr-1] != '\r'&& string1[chr_cntr-1] != '\n');
string1[chr_cntr] = '\0';
printf("\nstring1 has %d characters\n",chr_cntr-1);
printf("string = %s\n",string1);
return 0;
}
Is there an even more efficient way in which we can allocate memory for each single character each time before reading a character at that location?
And even if we manage to do that..won't it make the program more slower as we have to call the malloc function every time for each single character?
What do you people think would be a clever thing to do..allocate space for 500 characters at once or allocate space for 1 char at a time but use as many calls to malloc as there are characters to be stored??
Additionally, do we have special tag indicators for C/C++ programs exclusively? Just curious..
Last edited by aijazbaig1; July 9th, 2006 at 04:50 AM.
-
July 9th, 2006, 08:57 AM
#12
Re: getting string size at run time
 Originally Posted by aijazbaig1
Hello..
I have come up with the following code which uses a char pointer to allocate memory at run time on the heap.
You never mentioned whether you are trying to write a C++ program or a 'C' program.
The name of this forum has "C++" in its title. C and C++ are two separate languages. If you are writing a 'C' program, please say so, otherwise we must assume that you are using a C++ compiler, and you believe you are writing a C++ program.
If you are writing, or believe you're writing a C++ program, there is no need for any of the code you're writing now. The std::string and getline functions do all of this work for you. For a comparison between doing this in C++ and in 'C', here is a link to a paper written by the inventor of the C++ language. Please look at the difference between the C++ program on page 2, and the equivalent 'C' program on page 3.
http://www.research.att.com/~bs/new_learning.pdf
If it really and truly is a 'C' program and not a C++ program you are writing, then the most efficient ways is to preallocate a certain amount of memory, and then when the number of characters will exceed the preallocated amount, then and only then do you call realloc() (not malloc()).
Additionally, do we have special tag indicators for C/C++ programs exclusively? Just curious..
There is no such language as "C/C++". It's either 'C' or it's C++. Second, what do you mean by "tag indicator"? There is no such terminology used in C++ (or 'C') programming.
Regards,
Paul McKenzie
-
July 9th, 2006, 09:00 AM
#13
Re: getting string size at run time
i like to call C++
++C, hehee
-
July 9th, 2006, 10:47 AM
#14
Re: getting string size at run time
Hello.
I am indeed trying to write a C program not a C++ program. But after reading that paper; the link of which you provided in your reply,I am rather impressed by the ease of using C++ vis-a-vis C.
My objective isto get a fair grasp over C before plunging into C++.
Hence I don't mind doing some extra work in C. hehehe
How else will I realise the ease of using C++. Anyway, sorry for going off track. Heres my code , if you could till suggest a better alternative then please do let me know:
Code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *string1;
printf("enter string1\n");
string1 = (char *) malloc (500);
fgets(string1,500,stdin);
if (string1[strlen(string1)-1] == '\n') string1[strlen(string1)-1] = '\0';
printf("\nstring1 has %d characters\n",strlen(string1));
printf("string = %s\n",string1);
free(string1);
return 0;
}
-
July 9th, 2006, 11:34 AM
#15
Re: getting string size at run time
 Originally Posted by aijazbaig1
How else will I realise the ease of using C++. Anyway, sorry for going off track. Heres my code , if you could till suggest a better alternative then please do let me know:
Your code is quite good for a beginner. 
Here are a few comments and the most basic corrections:
Code:
#include <stdio.h>
/*#include <conio.h>*/ /* please, don't include headers you don't use, especially when these headers are non-standard */
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
int main(void) /* prototypes are a good thing : AFAIK functions without prototypes are deprecated */
{
char *string1;
printf("enter string1\n");
string1 = (char *) malloc (500); /* Style note : most C programmers don't use the (char*) cast here */
/* FAILURE TOLERANCE : You should check the return value of malloc */
if (!string1) {
fprintf(stderr, "Can't allocate input buffer!");
return EXIT_FAILURE;
}
if (NULL==fgets(string1,500,stdin)) {free(string1);return EXIT_SUCCESS;}
/* BUG : you don't test for the return value of fgets : If it is NULL, the string is not assigned at all */
if (string1[strlen(string1)-1] == '\n') string1[strlen(string1)-1] = '\0'; /* You should call strlen only once (more efficient) */
/* LIMITATION : The input string is limited to 500 characters with this program */
/* Potential problem : Truncation is not always the "correct" behavior when you get too many characters */
printf("\nstring1 has %u characters\n",(unsigned)strlen(string1)); /* BUG : strlen returns a size_t type : here, an int type was expected >*/
printf("string = %s\n",string1);
free(string1); /* Good : No memory leak */
return EXIT_SUCCESS;
}
The 500 characters limitation is serious : You don't use at all the power of dynamic allocation.
realloc can be used to avoid that limitation.
You should also write a separate function for the ReadLine operation.
See my post #9 for a better (but not perfect) example of ReadLine function.
What do you people think would be a clever thing to do..allocate space for 500 characters at once or allocate space for 1 char at a time but use as many calls to malloc as there are characters to be stored??
A clever thing to do would be to create a linked list of 64 or 128-bytes wide chunks of memory and fill them with characters (using fgets), allocating them with malloc...
Once we have read the whole line : Allocate a final buffer, large enough to contain all the chunks. Then, copy all the chunks of memory to the final buffer and free them.
Then, return the final buffer.
It is not extremely efficient since the minimal number of allocation is two.
In order to get better performances, it can be wise to use an automatic variable as first node of the linked list. Beware : You must not free() this node!
In that case, for small lines (e.g. less than 128 bytes), it will be very fast. The only overhead compared to an unsafe gets() would be one memory allocation (quite fast) and one copy of the string.
As an exercise, you could try to implement that.
Last edited by SuperKoko; July 9th, 2006 at 11:42 AM.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|