CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    19

    Question 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.

  2. #2
    Join Date
    Apr 2005
    Location
    Norway
    Posts
    3,934

    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

  3. #3
    Join Date
    Jan 2003
    Posts
    615

    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];

  4. #4
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    Re: getting string size at run time

    Why don't you simply use std::string?
    Marius Bancila
    Home Page
    My CodeGuru articles

    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.

  5. #5
    Join Date
    May 2005
    Posts
    40

    Exclamation 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

  6. #6
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    19

    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.

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: getting string size at run time

    Quote 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

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: getting string size at run time

    Quote 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

  9. #9
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    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()!

  10. #10
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    19

    Question 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?

  11. #11
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    19

    Lightbulb 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.

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: getting string size at run time

    Quote 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

  13. #13
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: getting string size at run time

    i like to call C++
    ++C, hehee

  14. #14
    Join Date
    Jun 2006
    Location
    Sweden
    Posts
    19

    Lightbulb 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;
    }

  15. #15
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: getting string size at run time

    Quote 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()!

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured