-
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.
-
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
-
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];
-
Re: getting string size at run time
Why don't you simply use std::string?
-
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
-
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.
-
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
-
Re: getting string size at run time
Quote:
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
-
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.
-
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?
-
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..
-
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()).
Quote:
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
-
Re: getting string size at run time
i like to call C++
++C, hehee
-
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;
}
-
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. :thumb:
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.
Quote:
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.
-
Re: getting string size at run time
Quote:
Originally Posted by aijazbaig1
My objective is to get a fair grasp over C before plunging into C++.
It's generally considered better to plunge straight into C++ if that is your end objective, otherwise you will learn a whole lot of C idioms that would be considered either unnecessary or bad practice under C++.
I know from experience of working with C for 10 years before moving to C++. My early programs are a horrible mish-mash of C and C++ styles as I slowly got to understand C++ and object orientated programming.
-
Re: getting string size at run time
Quote:
Originally Posted by aijazbaig1
My objective isto get a fair grasp over C before plunging into C++.
Why do you think you need to learn 'C' before learning C++?
http://www.parashift.com/c++-faq-lit....html#faq-28.2
Regards,
Paul McKenzie
-
Re: getting string size at run time
Quote:
Originally Posted by aijazbaig1
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?
Of course you can achieve that. You can write a linked list of characters. And you will get what you want. But allocating a smaller chunk and then doubling the size each time you exceed the limit would be better.
Jump to C++ though, there are many more things to learn that to keep wondering about character arrays and how to deal with them. Quicker programming is the need of the hour and the world is moving fast in terms of development technologies unless C-styles strings are part of your curriculum. ;)
-
Re: getting string size at run time
Hello.
Thanks a lot for so many wonderful comments that I received. Well this has put me into some kinda dilemma if I should abandon what I am presently doing with C?
Well, another reason why Im learning C is that I would be taking a course later in the fall semester on Operating systems concepts and a lot of code is still written in C and some in Java( as the book says that multithreading cannot be easily implemented using C ).
So heres the deal, my main intention is to be able to acquire enough skills to create windows based applications using VC++ but I still dont wanna go down on the implementation part in that course which I mentioned above..
Dont know where to head now..can I start with VC++ afresh..I have a book by gary bronson for VC++ exclusively but a whole bunch on C..is it possible to keep track of both if I ultimately decide to swim in both??..
Guys help me here..life sure is a big roundabout...
Best Regards,
Aijaz Baig.
-
Re: getting string size at run time
Quote:
Originally Posted by aijazbaig1
Hello.
Thanks a lot for so many wonderful comments that I received. Well this has put me into some kinda dilemma if I should abandon what I am presently doing with C?
There are many persons, such as myself and others here, who program both in 'C' and C++.
The trick is to know when to use 'C' techniques and when to use C++ techniques. If the programmer is disciplined and studied C++ properly, he/she can code correct C++ and have no "bad" influences brought into the program from their C background.
However, from my experience, there are still a lot of 'C' programmers who bring into a C++ program a lot of 'C' style coding, bringing about disastrous results (both in code maintenance and runtime bugs). These programmers are basically 'C' programmers who believed that since 'C' looks like C++, they can use the same techniques in a C++ program, and for the most part "winging it" (for those who are not familiar with the term "winging it", here it is from an online thesaurus):
Quote:
wing it
To say or do something without preparation, forethought, or sufficient information or experience; improvise
A quick look through some threads here have demonstrated this problem.
Quote:
Well, another reason why Im learning C is that I would be taking a course later in the fall semester on Operating systems concepts and a lot of code is still written in C and some in Java( as the book says that multithreading cannot be easily implemented using C ).
Another wrinkle is Java. That is another issue that has been discussed here a lot, and the big issue is Java programmers trying C++ and "winging it" on the C++ side. The C++ programs written by these particular Java programmers are just as, if not more, disastrous than 'C' programmers who "wing it" with their C++ programs.
Quote:
So heres the deal, my main intention is to be able to acquire enough skills to create windows based applications using VC++
Well, you need to learn the C++ part of VC++ first.
Quote:
Dont know where to head now..can I start with VC++ afresh..I have a book by gary bronson for VC++ exclusively but a whole bunch on C..is it possible to keep track of both if I ultimately decide to swim in both??..
Hard to say. However, when you're coding in C++, always think in terms of C++ first, and a 'C' based solution second. In other words, use vector, std::string, etc. instead of coding these yourself, etc.
I would get Accelerated C++ by Koenig & Moo. This introduces C++ to the programmer who already knows 'C' or some other language, and gets them on the right track.
Regards,
Paul McKenzie
-
Re: getting string size at run time
Quote:
Originally Posted by JohnW@Wessex
It's generally considered better to plunge straight into C++ if that is your end objective, otherwise you will learn a whole lot of C idioms that would be considered either unnecessary or bad practice under C++.
Yes, but I think that it is mainly due to programmer's lazyness... And the lack of understanding that C and C++ are two different languages...
I mean that C doesn't "pollute the mind" like many guys say for BASIC.
No... C doesn't pollute the mind.
aijazbaig1 : If you are aware of that issue you can learn C or C++ first... It should not matter that much.
But don't forget that you must not blindly apply what you have learnt in C in C++ ... You must try to find a better (more C++-ish) way to do things. It is an active learning process.
After all... I started with ugly GOTO-ish BASIC... Writing spaghetti code. But I don't program in C++ like I did in BASIC.
Similarly, at the start of my learning curve of C++, most information I got about C++ was on the C-with-classes subset of C++.
And also, don't forget that sometimes (not for everybody) very high-level concepts such as OOP are impossible to learn without understanding why they are useful... And sometimes you can only understand why you need them if you learnt to program with an object-based language (or subset of language)... And the object-based system can be well understood if you learn procedural programming...
Don't forget that OO features are a superset of object-based features which are a superset of procedural features.
I said that, because I have seen a lot of Java programmers programming with a much worst style than I could ever think of... They didn't even understood procedural concepts.
That's probably because, OO concepts are the not intuitive (at least for most people)... And if you think that they're really intuitive and easily applicable... You are either a genious or don't get them at all. With a bad understanding of OO, you'll get more productive, and produce more extensible code in a functional language... or even a procedural language.
Quote:
Well, another reason why Im learning C is that I would be taking a course later in the fall semester on Operating systems concepts and a lot of code is still written in C and some in Java( as the book says that multithreading cannot be easily implemented using C ).
Well, in my experience, C and C++ are the best languages for multithreading (even if it is quite difficult to write in a thread-safe way)... They have no builtin support for multithreading but they can use all the various synchronisation objects & multithreading objects which exists in the world... Java has a very simple but limited concept of thread synchronisation which is good for beginners but far less powerful than C and C++.
And, of course, if you want to understand how the OS works, Java is very bad at that.
C and assembly language are the best for that (Linux is programmed in C).
-
Re: getting string size at run time
Quote:
Originally Posted by Paul McKenzie
However, from my experience, there are still a lot of 'C' programmers who bring into a C++ program a lot of 'C' style coding, bringing about disastrous results (both in code maintenance and runtime bugs). These programmers are basically 'C' programmers who believed that since 'C' looks like C++, they can use the same techniques in a C++ program, and for the most part "winging it"
It was the story with me as well when I knew only C and was to code in C++. I started rightaway with the project coding in C style. Thank God, that things went fine even then and I did not mess it up - however when I think back, I can just imagine how much value I could have had added to the project had I been aware of C++ and used it well.
C to C++ is a big move and the basic ideology is different. To figure out and understand the essence of OOP is tough when you take this move but once you get to know it better in "your own words" and not "bookish terms", there is a big difference.
-
Re: getting string size at run time
Java has a standard library for threads but part of the problem is that there is no RAII in Java except for memory, so any thread resource like a mutex must be explicitly released after it is acquired. Of course they do have the "finally..." block to cope with it but it still puts the burden on the programmer. (Garbage collection doesn't work with resources like mutexes).
I have seen some Java code and actually I find a lot of it is overly procedural too. They have switch..case in Java and it is often overused, as are abundant numbers of 'if' statements where interfaces and polymorphism could be used instead. Changing language doesn't make a bad programmer into a good one.
It can be useful to know C as a language, partly because there are projects done in C, particularly in the embedded world, and also partly because a lot of the work you would be doing as a C++ programmer would involve supporting, maintaining and modifying other people's code as well as writing your own, and you would need to know C for that. In addition, if you write a C++ library it is quite likely you might want to give it a "C" interface and you would need to know what that means.
(My opinion on that matter is that you should give it both a C and a C++ interface and that the library should preferably be written in C++).
-
Re: getting string size at run time
Quote:
Originally Posted by Paul McKenzie
These programmers are basically 'C' programmers who believed that since 'C' looks like C++, they can use the same techniques in a C++ program, and for the most part "winging it"
For me it wasn't a deliberate decision to "wing it". At the time, I had put forward the idea to use C++ for the next project as it appeared to have, as standard, many of the things I had been coding the 'hard way' in C (and assembler). Unfortunately I was tasked to write the new code whilst trying to learn C++. This meant that my code started with a rather high C to C++ ratio. By the time I got sent on a training course, a substantial amount of code had been written. Eventually you are made to pay for this lack of training when you are tasked to maintain your old code :sick:.