monkey_king 39 Junior Poster

Yes.

if((ifd=open(filename,O_RDONLY))<3)

means:
1. assign the value returned by open to ifd
2. compare it to 3
whereas

if(ifd=open(filename,O_RDONLY)<3)

means:
1. compare the value returned by open to 3
2. assign the boolean result of the comparison to ifd

Thanks
that clarified it.

monkey_king 39 Junior Poster

Thanks for all your replies,
but it seems that its not possible to use posix read to read files larger than 2.1 gig.
This is according to the uberpenguin linus
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=e28cc715

At somepoint I guess it was possible but the kernel has regressed to only allow smaller chunks being read.

kernelsourcetree/fs/read_write.c

/*
 * rw_verify_area doesn't like huge counts. We limit
 * them to something that fits in "int" so that others
 * won't have to do range checks all the time.
 */
#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)

int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count);

This was rather annoying, it would have been nice if this had been documented outside of the kernelsource and kernelmailinglist.

monkey_king 39 Junior Poster

Hi,
Can someone elaborate why the following (the if conditional) differs

int main(){
  const char *filename = "test.txt";
  int ifd;
  if((ifd=open(filename,O_RDONLY))<3)
    err(EX_NOINPUT, "%s", filename);
  fprintf(stderr,"ifd is:%d\n",ifd);
  off_t bytes_in = lseek(ifd, (off_t)(-4), SEEK_END);
  return 0;
}

vs

int main(){
  const char *filename = "test.txt";
  int ifd;
  if(ifd=open(filename,O_RDONLY)<3)
    err(EX_NOINPUT, "%s", filename);
  fprintf(stderr,"ifd is:%d\n",ifd);
  off_t bytes_in = lseek(ifd, (off_t)(-4), SEEK_END);
  return 0;
}

Basicly it looks like adding additional paranthesis, makes the conditional test on the evaluation of the rval. And the assignment is a sideeffect?

thanks

monkey_king 39 Junior Poster

It's defined on line 166 of http://fxr.googlebit.com/source/lib/libz/zconf.h (same library different site) which is included in zlib.h which your file includes. It checks for this STDC value which I assume means whether the system supports standard C. It seems to expand to a prototype of the functions. I know precious little about *nix, but I was curious myself so hopefully that gives you a head start to find more info on it.

Ahh thanks.
That was helpfull :)
btw how did you find this, what did you google?
I had problems finding useful results because of the name "OF"
Thanks again.

monkey_king 39 Junior Poster

Run it through a debugger
assuming you are using gcc

$gcc -ggdb file.c
$gdb ./a.out
$run
$bt

This will tell you on which line the error originated.

You can also look into valgrind

good luck

monkey_king 39 Junior Poster

I've been programmin on and off for some time.
But today I saw something I hadnt seen before

Some thing like

void error            OF((const char *msg));
void gz_compress      OF((FILE   *in, gzFile out));
#ifdef USE_MMAP
int  gz_compress_mmap OF((FILE   *in, gzFile out));
#endif
void gz_uncompress    OF((gzFile in, FILE   *out));
void file_compress    OF((char  *file, char *mode));
void file_uncompress  OF((char  *file));
int  main             OF((int argc, char *argv[]));

Can anyone clarify the what the OF does?

thanks

monkey_king 39 Junior Poster

This works like a charm. Thanks!!

Can you explain the meaning of **getstring(int x, int y), the two **?

There is a relationship between pointer and arrays.
so int a[] can be written as int *a,
so a double array int a[][], can be written as int **a.

This is simlified, but its the general idea.
good luck :)

monkey_king 39 Junior Poster

I have no idea what you are asking.

what do you mean by "running online"

monkey_king 39 Junior Poster

There shouldn't be anything wrong with returning a 2-dim array.
Something like the following should work.

#include <iostream>
#include <string>

std::string **getstring(int x, int y){
  std::string **var = new std::string*[x];
  for (int i=0;i<x;i++)
    var[i]=new std::string[y];
  return var;
}

int main(){
  std::string **tmp = getstring(5,10);
  return 0;
}

This assumes the same number of elements at each line, and you should cleanup the memory.

good luck

monkey_king 39 Junior Poster

Don't you think that fsize better works on a FILE *, rather than char *?

The last time I checked fsize was a windows specific command.
I'm using linux.

The first function in the codesample I supplied is a function called fsize,
that just returns the number of bytes for the file.

monkey_king 39 Junior Poster

Hi I've found a strange problem on ubuntu64bit, that limits the data you are allowed to allocate on a 64bit platform using the c function 'read()'

The following program wont allow to allocate more that 2.1gig memory.

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <fcntl.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/stat.h>

// get bytesize of file
size_t fsize(const char* fname){
  struct stat st ;
  stat(fname,&st);
  return st.st_size;
}

int main() {
  const char *infile = "bigfile.dat";
  int fd;
  size_t bytes_read, bytes_expected = fsize(infile);
  char *data;
 printf("\nLONG_MAX:%lu\n",LONG_MAX);

  if ((fd = open(infile,O_RDONLY)) < 0)
    err(EX_NOINPUT, "%s", infile);

  if ((data =(char *) malloc(bytes_expected)) == NULL)
    err(EX_OSERR, "data malloc");


  bytes_read = read(fd, data, bytes_expected);

  if (bytes_read != bytes_expected)
    err(EX_DATAERR, "Read only %lu of %lu bytes",bytes_read, bytes_expected);

  /* ... operate on data ... */

  free(data);

  exit(EX_OK);
}

./a.out
LONG_MAX:9223372036854775807
a.out: Read only 2147479552 of 2163946253 bytes: Success

According to man 2 read, the maximum is limited by SSIZE_MAX
which is defined in

/usr/include/bits/posix1_lim.h
# define SSIZE_MAX LONG_MAX

And LONG_MAX is defined in /usr/include/limits.h as
# if __WORDSIZE == 64
# define LONG_MAX 9223372036854775807L
# else
# define LONG_MAX 2147483647L
# endif
# define LONG_MIN (-LONG_MAX - 1L)

Either this is a bug in the ubuntu buildsystem,
or my build system is broken.

Can anyone with a 64 try to run the above program.

btw

readelf -h ./a.out
ELF Header:
Magic: 7f 45 4c 46 …

monkey_king 39 Junior Poster

If the size is determined at runtime you need a full fleged dynamic memory version. Something like

#include <iostream>


int **allocs(int x,int y){
  int **ret  = new int*[x];
  for(int i=0;i<x;i++)
    ret[i] = new int[y];
  return ret;

}


int main(){
  int **array = allocs(4,5);
  int p = 0;

  for(int i=0;i<4;i++)
    for(int j=0;j<5;j++)
      array[i][j] = p++;

}
monkey_king 39 Junior Poster

Just try to do the program,
when its done, it should be clear what should be pointers.

monkey_king 39 Junior Poster

Hi omir
People are normally quite friendly inhere,
but you should ask a specific question.

good luck

monkey_king 39 Junior Poster

So you essentially want a truthtable.
The dimension of this truthtable is n*2^n, where n is the number of coin throws.
I once did this program, and I have to agree with you,
it was annoyingly difficult to come up with,
and I never had a beautifull solution.
I think I had 2-loops and 2 extra counters.
the trick is to start from the column1 and then fill up with 1's untill you reach halfway, and then zeroes.
in column2 you would fill up with 1's quaterdown, zeroes till halfdown, 1' till 3quaterdown and 0's the rest

monkey_king 39 Junior Poster

Hi I got a code that in pseudo dos something like

ifstream os;
while(os.oef()){
   os.getline(buffer,length);
}

If some condition is met,
I'd like to be able to jump back to the previous line,
such that the next getline will give the line just-read in, at a later time in my execution timeline.

Is this possible?

thanks

monkey_king 39 Junior Poster

What would your rule be for definingen when a token/line is invalid?
I would check the the number of tokens in each class is first 2, then 8

Or do you want a more elaborate check?

monkey_king 39 Junior Poster

skynet

monkey_king 39 Junior Poster

You can use strchr function with space as the delimiter to mark the boundary of the first token and then read it accordingly.

Ahh, cheers
Thanks!
This will come in handy

monkey_king 39 Junior Poster

I don't know very much C programming but I am pretty good at google. http://www.elook.org/programming/c/strtok.html

I'm aware of the fact that I can tokenize the entire string,
but if I (dependent on the first token) just want the rest of the line,
without the need to tokenize it. How do I do that

monkey_king 39 Junior Poster

If I simply just want to tokenize the first element of a string and then output the remainder of the string, how can this be accomplished?

thanks

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

int main(){
  const char* line= "0 firstline";
  char* l = strdup(line);
  printf("beforeToknization:\t%s\n",l);
  char *tok = strtok(l," ");
  printf("firstToken:%s\trestOfLine:%s\n",tok,l);
  return 0;
}
./a.out
beforeToknization:      0 firstline
firstToken:0    restOfLine:0
monkey_king 39 Junior Poster

Thanks ppl,
I need to keep track of the indices,
so the strtok approch wont work.

But thanks again.

monkey_king 39 Junior Poster

Hi,
given a cstring, I need to extract the digits in it, the digits are prefixed with either a '+' or '-'. Like

,.,.,.,+3ACT,.,.,.,.-12,.,.,.,.,.,.,.,actgncgt
#OUTPUT
3
12

I've made a working program that does what I want,
but it seems overly complicated.
Does anyone have an idea if this can be done smarter, better, faster?

Thanks in advance

Btw I checked the program with valgrind and there are no leaks or errors

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
  char tmp_array[100];
  const char* seq = "+1236,,..,,actgn+3ACT-4CCCC";
  printf("%s\n",seq);

  for(int i=0;i<strlen(seq);i++){
    if(seq[i]!='+'&&seq[i]!='-')
      continue;
    int j=i+1;
    while(j<strlen(seq)){
      if(seq[j]>='0' &&seq[j]<='9'){
	j++;
      }else
	break;
      
    }
    strncpy(tmp_array,seq+i+1,j-i-1);
    tmp_array[j-i-1]='\0';
    printf("numbers in substrings are: %d\n",atoi(tmp_array));
  }
  
  return 0;
}
monkey_king 39 Junior Poster

post your compile errors

monkey_king 39 Junior Poster

Could you try doing a
'ldd libPixyCANopen.so'

monkey_king 39 Junior Poster

Firstly I see that you are Using a outdated compiler. Though it is not il-legal to use it . It is considered better if you use a modern compiler like CODE::BLOCKs etc.

I normally wont go into small errors in other peoples posting,
but it should be noted that code::blocks is an ide.
The compiler is most likely(depending on the setup) the mingw compiler. The mingw is a subset of the gnu toolchain. :)
I dont like being a correction nazi,
but the difference between compiler and ide/editor is quite important.
cheers!


To the original poster.

Is it nescesarry to use static variables for you program?

Sky Diploma commented: Oops! My Bad. +3
monkey_king 39 Junior Poster

It's shouldn't be necessary to use extern,
generally you have access to all the public variables and function in the symboltable, but only the externed are required to have the same signature, from version to version.
This is atleast how it should be.

http://people.redhat.com/drepper/dsohowto.pdf

try doing a ldd on your compiled files to see if anything is missing

monkey_king 39 Junior Poster

I think it depends on what you are doing with the file.
I've found that the FILE, strtok is by far the fastest way of reading in data.
I've been using flat files, (same number of columns in all lines).
On the scale of several gigabytes.

And avoiding the c++ streams was faster.
But I've heard rumors that you can tweak the fstream with a fsetbuf,
that should make it faster.

monkey_king 39 Junior Poster

Yes,
you've added 'delete []', and have to dereference the double pointers.

Thanks for your help again ancient dragon.

monkey_king 39 Junior Poster

Thanks ancient dragon,
the trick was passing a pointer pointer then.

@arkm

The programming problem is simple.
check if a char* contains a trailing slash,
otherwise update the char*, so that it does.

I'm all ears for a more simple version,not using std::string

monkey_king 39 Junior Poster

Hmm thanks for the char[] approach.

But I cant nail down my problem with the updated cstring.
The following code

#include<iostream>
#include<cstring>

void fix_name(char *name){
  printf("pointer in function arg: %p\n",name);
  if(name[strlen(name)-1]!='/'){
    char *tmp = new char[(strlen(name)+1)];
    strcpy(tmp,name);
    tmp[strlen(name)] = '/';
    printf("content of new cstring: %s\n",tmp);
    printf("pointer of new cstring %p\n",tmp);
    name=tmp;
    printf("pointer of function arg: %p\n",name);
  }
}

int main(int argc, char** argv){
  char sdsd[] = "asf/asdf";

  printf("%s\n",sdsd);
  fix_name(sdsd);
  printf("%s\n",sdsd);
  return 0;
}

which gives rise to

./a.out
asf/asdf
pointer in function arg: 0x7fff0ef7b5e0
content of new cstring: asf/asdf/
pointer of new cstring 0x23f4010
pointer of function arg: 0x23f4010
asf/asdf

Do I need to give my function that should update my cstring a **char pointer, instead of a *char pointer?

thanks in advance

monkey_king 39 Junior Poster

Hi
I'm having a very basic newbie problem,
The compiler forces me to do a strdup (because of cons correctness),
can I void the extra line in my code, and then I cant seem to update my array
after the funciton call

void fix_name(char *name){
  if(name[strlen(name)-1]!='/'){
    char *tmp = new char[(strlen(name)+1)];
    strcpy(tmp,name);
    tmp[strlen(name)] = '/';
    printf("%s\n",tmp);
    name=tmp;
  }
}

int main(int argc, char** argv){
  const char* sds = "asf/asdf";
  const char* sdsd =strdup(sds)
  printf("%s\n",sdsd);
  (fix_name(sdsd));
  printf("%s\n",sdsd);
  return 0;
}
monkey_king 39 Junior Poster

Cheers arkM,

I will for sure look into this.

The avl is not part of the stl right?
So I have to make this one up.


As it is, the lookup map, takes aprox 3-4 gig memory,
I have 8 gig, but this is really the limit.
35million keys, each with a int[5] as value.

So i really can't just malloc huge amounts.
Or maybe I dont understand you...

The files I read are flatfiles, same amount of columns on each line,
so you are saying I should just buffer huge huge amounts.
And then manually tokenize by newlines, and then item seperate it?

Thanks for your advice,

monkey_king 39 Junior Poster

I'm parsing 900 gig of textfiles
Using std::string as opposed to char* directly from getline,
takes around 40-60% longer.

monkey_king 39 Junior Poster

Thanks for your response.

Is the const_cast necessary because i definded my map as a

typedef std::map <const char*,int> aMap;

instead of

typedef std::map <char*,int> aMap;

Having a key as const in a map is to prefere right?

thanks again

monkey_king 39 Junior Poster

Cheers arkM,

I have no idea what happened here...

But the const_cast is not really necessary, is it?

monkey_king 39 Junior Poster

For anyone that cares,
this seems to do the trick.
But it is important that the item decleration is used directly at the assignmen operator

[TEX=c++]
my_map::value_type item = *it;
data.erase(it);
free (item.first);
[/TEX]

monkey_king 39 Junior Poster

c is generally slow compared to other programming language.
Gone through your coding and nothing seems wrong.

Just out of curiosity, what languages should be faster?
Assembler, fortran?

monkey_king 39 Junior Poster

Hi,

  1. Question
    Why does valgrind complain?
    Conditional jump or move depends on uninitialised value(s)
    ==25636==    at 0x4C26D29: strlen (mc_replace_strmem.c:242)
    ==25636==    by 0x40060A: main (test.c:7)
  2. Question
    Strlen doesnt apparantly tell you how much space you have in your array, but the number of chars til '\0'.
    I my case i've alloced space for 80 chars,
    so when I'm strduping, will my new array also hold 80 or just till the strlen of the old char array?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
  char* str1 =(char *) malloc(80*sizeof(char));
  printf("length of str1:%d\n",(int)strlen(str1));
  str1 = "test_of_string\n";
  printf("length of str1:%d\n",(int)strlen(str1));

  char* str2 = strdup(str1);
  printf("length of str1:%d\n",(int)strlen(str2));
  return 0;
}

thanks

monkey_king 39 Junior Poster

Thanks people,
very helpfull indeed.

Thanks

monkey_king 39 Junior Poster

Hi I stumpled upon some c-code,
which syntactically is different from what I've seen before.

  1. first
    void strreverse(char* begin, char* end) {
      char aux;
      while(end>begin)
        aux=*end, *end--=*begin, *begin++=aux;
    }

    Would this be the same as

    void strreverse(char* begin, char* end) {
      char aux;
      while(end>begin){
        aux=*end;
        *end--=*begin;
        *begin++=aux;
    }
  2. second
    void itoa(int value, char* str, int base) {
            
      static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
      char* wstr=str;
      int sign;
      div_t res;
      
    
            
      // Validate base
      if (base<2 || base>35){ *wstr='\0'; return; }
      
      // Take care of sign
      if ((sign=value) < 0) value = -value;
      
      // Conversion. Number is reversed.
      do {
        res = div(value,base);
        *wstr++ = num[res.rem];
      }while(value=res.quot);
      if(sign<0) *wstr++='-';
      *wstr='\0';
      
      // Reverse string
      strreverse(str,wstr-1);
    }

    What is happening here especially the res.quot

Thanks in advance

monkey_king 39 Junior Poster

Well, this isn't at the bitlevel,

you are interpreting the ascii values '0' '1' as bit 0 and bit 1.

If you are interested in this bitlevel stuff,
you should look into the shift operations. like

unsigned char x=7;
unsigned char y=x<<1;
//y is now 7 times 2

But it looks nice your code,
one thing though, you don't need

if (carry == 1)
    *temp++ = carry;
//just
if(carray)

A good exercise is to write you addition program with a non fixed base like,


digit_n = (digit_{n-1}\textrm{ div }base) + (digit_n\textrm{ mod }base)

monkey_king 39 Junior Poster

Yes I know,
this is what I write in my original post.

How do I free the memor, that I've allocated.

monkey_king 39 Junior Poster

It's in the nature of finite precision.
Theres not much you can do about it.

there a basicly two kinds of datatypes.
1. integral
2. float

integral being, int, char, byte etc
floats being, float, double

integral is always precise, floating values are more obscure

What numerical libraries do is to check for equality within a tolerance like

float one = 0;
float two = 0.0000001

 //wrong
if(one!=two)
  puts("not same");

//right
#define tole 0.000001
if(fabs(one-two)>tole)
  puts("not same")

If you need it depends on your context,
if you just want the value, then you shouldn't care.

But if your program has a branchpoint depending on this value,
you should go the "within tolerance" way.

on a sidenote.
floats are only precise to the 7th or 8th digit,
whereas double are to the 23thd

good luck

monkey_king 39 Junior Poster

Hi,
can anyone tell me why i can't clean up the memory,
and maybe a small solution.

I'm allocing memory with strdup for each key,
but I cant figure out how to erase the key with free.

Before anyone starts talking about mixing c++ and c,
I know it's generally a bad idea but std::strings are to slow.

#include<iostream>

#include<cstring> //for cstring functions
#include<map> //associative array
#include<cstdlib> 


struct cmp_str {
  bool operator()(const char *a,const  char *b) {
    return std::strcmp(a, b) < 0;
  }
};

void printMap(std::map<const char*,int,cmp_str> &asso){
  for(std::map<const char*,int>::const_iterator it = asso.begin(); it != asso.end(); ++it){
    printf("%s:\t %d\n",it->first,it->second);
  }
}



std::map<const char*,int,cmp_str> build(){
  std::map<const char*, int,cmp_str> asso;
  
  const char *text = "does is work";
  char *tmp=NULL;
  tmp = strtok(strdup(text)," \t");
  
  while(tmp!=NULL){
    asso[strdup(tmp)] = 1;
    tmp=strtok(NULL," \t");
  }
  return asso;
}

void cleanup(std::map<const char*,int,cmp_str> &asso){
  std::map<const char*,int,cmp_str>::iterator it;
  asso.erase(asso.begin(),asso.end());
}


int main(int argc, char** argv){
  std::map <const char*, int,cmp_str> asso = build();
  printMap(asso);
  printf("should return 1: %d\n",asso["is"]);
  printf("should return 0: %d\n",asso["0"]);
  cleanup(asso);
  return 0;
}
monkey_king 39 Junior Poster

use the following code for random numbers between limits:

Random* r = new Random();

int x=r->Next(10,21);

this will create random numbers between 10 and 20!

What have you included,
this doesn't look like std c++

monkey_king 39 Junior Poster
void initialize_file(Horses temp_array[]) {
 string line;
 ifstream HorsesFile ("HorsesFile.txt");
 if (HorsesFile.is_open()) {
   while (! HorsesFile.eof() ) {
     getline (HorsesFile,line);
     cout<<line<<endl;
 }
 HorsesFile.close();
 }
 else cout << "Unable to open file"; 
}

What is the format of your input file,
I cant see how the file is structured.
Maybe you should tell us.

monkey_king 39 Junior Poster

Write an example on datainput, and dataoutput,
like


int inPut=1234;
char *output= \\how do I convert 1234 to char*

monkey_king 39 Junior Poster

I think this is an excellent example of why humans shouldnt use automated translation programs. Like babelfish and translate.google.

I understand he wants to write a calculator that uses polish reversed notation.

I don't know if he wants std array[] or stl style array http://www.josuttis.com/cppcode/array.html

monkey_king 39 Junior Poster

no i went thru the link but i needed code just go thru my code

#include<unistd.h>

int main()
{
	int n2,n1;
	int randNum;
	int index;
 int lowest=10, highest=1000; 

	
for(index=0; index<5; index++)
	{ 
    randNum = (int)((highest-lowest)*rand()/(RAND_MAX + 1.0))+lowest; 
	printf("%d\n",randNum);
    }
	return 0;  
}

So whats the problem?