You do indeed have to keep track of it. Once you malloc a chunk of memory, you can't ask the system what the size of that chunk of memory is; it wouldn't know. If you need to know, record it yourself at the same time you malloc (and modify it if you change the amount of memory that you're reserving with realloc()).
Sorry guys, but I really don't see why we'd need all that work when compared to vectors. It just seems so much work :S I guess that's C, but let me ask you something else:


Code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

int main ();
string find_and_replace(string source, string const find, string const replace);
void comment_lines_starting_with_print_on_file (char input_filename[], char output_filename[]);

int main () {
   char inputFile[] = "samplecode.py";
   char outputFile[] = "output.py";
   comment_lines_starting_with_print_on_file(inputFile, outputFile);
   
   return 0;
}

void comment_lines_starting_with_print_on_file (char input_filename[], char output_filename[]) {
   /* This functions opens a file, comments out (#) all lines starting with "print" and makes a new file with the changes */
   
   string line;
   ifstream myfile (input_filename);
   int loop = 0;
   
   string* array = (string*)malloc(10*sizeof(string));
   
   //int* array = (int*)malloc(120*sizeof(int));
   
   //vector<string> array;
   vector<string> array_no_tabs;
   
   if (myfile.is_open()) {
      while (! myfile.eof() ) {
         getline (myfile,line);
         //array.push_back(line);
         array[loop] = line;
         array_no_tabs.push_back(find_and_replace(line, "\t", ""));
         loop++;
      }
      myfile.close();
   }
   else {
      cout << "Unable to open file";
   }
   
   int i;
   for (i=0;i<(sizeof array/sizeof(string));i++) {
      if (array_no_tabs[i].substr(0,5) == "print") {
         array[i] = "#"+array[i];
      }
   }
   
   ofstream new_file;
   new_file.open (output_filename);
   
   for (i=0;i<(sizeof array/sizeof(string));i++) {
      new_file << array[i] << endl;
   }
   new_file.close();
}

string find_and_replace(string source, string const find, string const replace) {
   /* This functions find and replaces arg2 with arg3 in a string which is arg1, it returns a new string */
   
   for(string::size_type i = 0; (i = source.find(find, i)) != string::npos;)
   {
      source.replace(i, find.length(), replace);
      i += replace.length() - find.length() + 1;
   }
   return source;
}


In that code, I use:


Code:
(sizeof array/sizeof(string))


To get length of the array and the output is "Segmentation Fault", I don't really see what is wrong in getting the size that way. Thanks
Let's back up a bit and think about what your program does and how that should influence the design.

You're only reading a file line by line and replacing some of the text in that line with some other text (or inserting a # sign at the beginning). Processing a line doesn't require any context lines before or after the current line. So what I would do is:
  1. open input and output files
  2. read a line from input file
  3. do all processing on that line (remove tabs, insert #)
  4. write the line to the output file
  5. loop back to 2 until end of file
Of course, if the input and output filenames are the same, this won't work (since the file will be truncated before you read a line), so instead of opening the output file directly, I would open a temporary output file instead and then rename it to the output filename (overwriting the original) at the end.

Also, I noticed in your loop that you're checking myfile.eof(). With an ifstream (or really, anything derived from "ios" class), the eof flag doesn't get set until you try to read past the end of the file. If you only read up to the end, it doesn't get set, which means you have to check for eof right after a read. You should be checking for eof after reading a line and before trying to process that line:

Code:
  while (!getline(myfile, line).eof()) {
    // replace and insert characters here
    // write the line to the output file
  }

The code "getline(myfile, line).eof()" works because getline() returns a reference to myfile, so you're basically calling getline(myfile. line) and then myfile.eof() all in one statement. Neat, huh? πŸ™‚
As I already said in a previous thread of yours, and I believe Kllrnohj told you this too, sizeof() is a compile-time construct. It's not a function that runs at runtime, it's not strlen(), and it can't figure out how big arrays are. Since you are making an array of strings, by the way, it would make more sense to use a vector<std::string> here.
KermMartian wrote:
As I already said in a previous thread of yours, and I believe Kllrnohj told you this too, sizeof() is a compile-time construct. It's not a function that runs at runtime, it's not strlen(), and it can't figure out how big arrays are. Since you are making an array of strings, by the way, it would make more sense to use a vector<std::string> here.


I see then, which is what I used. However, some people here wanted me to use malloc( and I wanted to learn it. Maybe in this case I can't learn it.

Thanks.
So, on my blog I posted some code I'd like you guys to see.

To be precise, it's this post I'd like you to see.

I want you guy's opinions on the code πŸ™‚
ephan wrote:
I see then, which is what I used. However, some people here wanted me to use malloc( and I wanted to learn it. Maybe in this case I can't learn it.

Thanks.


You are writing C++, forget that malloc exists. Just don't use it. Write C++, not C. C++ has a ton of helper stuff that shields you from a *lot* of work that C requires, USE IT. Never use char*, always use std::string. Never use printf, always use cout. etc...

ephan wrote:
So, on my blog I posted some code I'd like you guys to see.

To be precise, it's this post I'd like you to see.

I want you guy's opinions on the code πŸ™‚


Well, you could do that (which isn't particularly efficient or clever, btw), or you could pick a better language for that sort of thing and do it in a single line (Python 3.0 - to run on 2.6 just change input() to raw_input()):


Code:
' '.join(map(lambda x: x[::-1], input().split()))
Kllrnohj wrote:
ephan wrote:
I see then, which is what I used. However, some people here wanted me to use malloc( and I wanted to learn it. Maybe in this case I can't learn it.

Thanks.


You are writing C++, forget that malloc exists. Just don't use it. Write C++, not C. C++ has a ton of helper stuff that shields you from a *lot* of work that C requires, USE IT. Never use char*, always use std::string. Never use printf, always use cout. etc...

ephan wrote:
So, on my blog I posted some code I'd like you guys to see.

To be precise, it's this post I'd like you to see.

I want you guy's opinions on the code πŸ™‚


Well, you could do that (which isn't particularly efficient or clever, btw), or you could pick a better language for that sort of thing and do it in a single line (Python 3.0 - to run on 2.6 just change input() to raw_input()):


Code:
' '.join(map(lambda x: x[::-1], input().split()))


But doing that stuff in Python is easy, hence I used C++, to learn more.

I already know Python for a long time, now I need to go lower, as you said in the other topic.
Kllrnohj wrote:
ephan wrote:
So, on my blog I posted some code I'd like you guys to see.

To be precise, it's this post I'd like you to see.

I want you guy's opinions on the code πŸ™‚


Well, you could do that (which isn't particularly efficient or clever, btw), or you could pick a better language for that sort of thing and do it in a single line (Python 3.0 - to run on 2.6 just change input() to raw_input()):


Code:
' '.join(map(lambda x: x[::-1], input().split()))

An even better language for this problem would be Bash:

Code:
rev

😁
christop wrote:
An even better language for this problem would be Bash:

Code:
rev

😁


No it isn't, because that does something different you idiot. πŸ˜› The equivalent of "rev" in Python is just [::-1] btw (so, reverse = mystr[::-1])

EDIT: But here is the C++ version (would work really well in C, too). It's in place and efficient.


Code:
#include <iostream>
#include <string>
using namespace std;

void swap(string& str, int a, int b) {
   if (str[a] != str[b]) {
      str[a] ^= str[b];
      str[b] ^= str[a];
      str[a] ^= str[b];
   }
}

void reverse(string& str, int start, int end) {
   while (start < end) {
      swap(str, start++, end--);
   }
}

int main() {
   string input;
   getline(cin, input);
   int j;
   int len = input.length();
   for (int i = 0; i < len; i = j + 1) {
      j = i + 1;
      while (j < len && input[j] != ' ') j++;
      reverse(input, i, j - 1);
   }
   cout << input;
   cin.get();
   return 0;
}
Kllrnohj wrote:
christop wrote:
An even better language for this problem would be Bash:

Code:
rev

😁


No it isn't, because that does something different you idiot. πŸ˜› The equivalent of "rev" in Python is just [::-1] btw (so, reverse = mystr[::-1])

Mine was a solution for reversing each line of text, not reversing words in a line. Idiot! πŸ˜›
christop wrote:
Mine was a solution for reversing each line of text, not reversing words in a line. Idiot! πŸ˜›



Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
    int n;
    scanf("%d", &n);

    //char * all_input[n];

    int i;
    for (i=0; i<n; i++) { //Noop n times
        char input[100];
        fgets(input, sizeof input, stdin);
        printf("%s", input);
    }

    return 0;
}


I am trying to get a number as input and then read a string n times and print it.

However, if I enter, for example, 1, the program closes, it should read 1 string.

Thanks πŸ™‚
ephan wrote:

Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
    int n;
    scanf("%d", &n);

    //char * all_input[n];

    int i;
    for (i=0; i<n; i++) { //Noop n times
        char input[100];
        fgets(input, sizeof input, stdin);
        printf("%s", input);
    }

    return 0;
}


I am trying to get a number as input and then read a string n times and print it.

However, if I enter, for example, 1, the program closes, it should read 1 string.

Thanks πŸ™‚

scanf() reads the numeric characters and stops before reading the newline character. By the time your first fgets() runs, it reads that first newline, so you're really getting an empty first line with that. The basic problem is that scanf doesn't differentiate between the different types of whitespace (you can use spaces, tabs, or newlines between its inputs), but fgets() does (it stops reading only at a newline), so it's tricky to mix functions like scanf() and fgets().

What you can do instead of scanf() is use fgets() to read the number into a string buffer, and then use sscanf() to scan that string for the number 'n'. It's a bit of a pain, but it should work the way you want it to.

Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
    char n_input[99];
    fgets(n_input, sizeof n_input, stdin);
    int n;
   
    sscanf(n_input, "%d", &n); //get the number of times out of n_input

    char * all_input[n]; //array that stores all inputs

    int i;
    for (i=0; i<n; i++) { //Noop n times to get n inputs
        char input[99];
        fgets(input, sizeof input, stdin);
       
        char * two_numbers[2];
       
        char * saveptr1;
        strtok_r(input, " ", &saveptr1);
       
        two_numbers[0] = input; //Get first number, still reversed
        two_numbers[1] = saveptr1; //Get second number, still reversed
       
        //all_input[i] = input; //append the input to all_input
    }

    return 0;
}


It worked, thanks a lot christop!

I have a new question though... How to declare an array of arrays of strings.

I want this:

[ ["hey", "dude"], ["what", "is], ["up", "man"] ]

I have no idea of how to declare it though. Thanks πŸ™‚
I believe that would be:
Code:
char* array[] = { {"Hey", "Dude"}, {"What", "Is"}, {"Up,", "Man"} };
_player1537 wrote:
I believe that would be:
Code:
char* array[] = { {"Hey", "Dude"}, {"What", "Is"}, {"Up,", "Man"} };


Missing one more []


Code:
char* sarr[2][2] = { { "Hey", "Man" }, { "What's", "Up?" } };
printf("%s %s, %s %s", sarr[0][0], sarr[0][1], sarr[1][0], sarr[1][1]);
Actually, I was not clear, I need to declare it as empty, I won't set the values when I declare it, I'll add them later.

Either way, I managed to declare it, but when I try to add values:


Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
    char n_input[99];
    fgets(n_input, sizeof n_input, stdin);
    int n;
   
    sscanf(n_input, "%d", &n); //get the number of times out of n_input

    char * all_input[n][2]; //array that stores all inputs

    int i;
    for (i=0; i<n; i++) { //Noop n times to get n inputs
        char input[99];
        fgets(input, sizeof input, stdin);
       
        char * two_numbers[2];
       
        char * saveptr1;
        strtok_r(input, " ", &saveptr1);
       
        two_numbers[0] = input; //Get first number, still reversed
        two_numbers[1] = saveptr1; //Get second number, still reversed
       
        all_input[i] = two_numbers; //append the input to all_input
    }

    return 0;
}


The line "all_input[i] = two_numbers", when I compile I get:

"error: incompatible types when assigning to type β€˜char *[2]’ from type β€˜char **’"

I think that I am declaring two_numbers okay, and that it is char *[2].

Any idea?

Thanks
Don't forget that if you have an n by 2 array of char*s, you still need to malloc n*2 pieces of memory to store in each element. As far as I can tell, you're repeatedly reusing two_numbers, so in the end every element of your array will be the same (best case) or referring to nothing, since two_numbers is declared inside a nested scope (worst case).
I was reading a CPlusPlus.com tutorial's on C++ and learnt a lot of stuff (still haven't finished it), and I have a question:


Code:

#include <iostream>
using namespace std;

int main ()
{
  char terry[] = "Hello";
 
  if (*(terry+5) == "\0") {
    cout << "true";
  }
 
  return 0;
}


The thing is, terry is an address. terry+5 is an address to the "\0", the end of the character.

So it's like:

H E L L O \0
^
terry

When compiling, G++ says "work.cpp:8:21: error: ISO C++ forbids comparison between pointer and integer"

The thing is, *(terry+5) is not a pointer, it's "\0", I think.
--------------------------------------------------------------------------

Now concerning your answer Kerm, thanks a lot, now that I learnt more about pointers (http://www.cplusplus.com/doc/tutorial/pointers/) I'll try and rewrite my code. Also yeah it's quite bad to declare the array everytime I run the loop.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
» Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
» View previous topic :: View next topic  
Page 9 of 10
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement