William Hemsworth 1,339 Posting Virtuoso

Creating your own strcat is nothing, it takes literally a couple of lines.

void my_strcat(char *dest, char *source) {
  // Find null-terminator
  while ( *++dest );

  // Add new string
  while ( *dest++ = *source++ );
}

Making it safe would be the next problem. But think about what Lerner is telling you, you're assuming what the user inputs will be shorter than 128 characters, if you can't use std::strings, try learning how to use dynamic memory, or validating your input.

William Hemsworth 1,339 Posting Virtuoso

Sorry, my mistake :P

String& String::operator +=(char* other)   {
  // Temporarily store the old length (for copying chars)
  size_t oldLength = m_length;

  // New size of string
  m_length += strlen(other);

  // Allocate enough space for the new string
  char *new_str = new char[m_length];

  // Copy string without null-terminator
  for (size_t i = 0; i < oldLength; ++i)
    new_str[i] = m_buffer[i];

  for (size_t i = oldLength, j = 0; i < m_length; ++i, ++j)
    new_str[i] = other[i];

  // Delete old chars
  delete[] m_buffer;

  // Assign new string
  m_buffer = new_str;

  return *this;
}

Haven't really tried compiling this, but I think it's right this time.

shasha821110 commented: good, expert, kind +1
William Hemsworth 1,339 Posting Virtuoso

Just write your own loop to copy chars without the null-terminator?
However, on this line:

m_length = [B]strlen[/B](m_buffer) + [B]strlen[/B](other) + 1;

You are using a function which relies on the null-terminator at the end of the string, so you will have to keep track of the string length yourself while adding characters to it. Something like this perhaps?

String& String::operator +=(char* other)   {
  // Temporarily store the old length (for copying chars)
  size_t oldLength = m_length;

  // New size of string
  m_length += strlen(other);

  // Allocate enough space for the new string
  char *new_str = new char[m_length];

  // Copy string without null-terminator
  for (size_t i = 0; i < oldLength; ++i)
    new_str[i] = m_buffer[i];

  // Delete old chars
  delete[] m_buffer;

  // Assign new string
  m_buffer = new_str;

  return *this;
}

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

... Forget this post :)

William Hemsworth 1,339 Posting Virtuoso

Why are you using the preprocessor for this?
This compiles and works for me:

#include <iostream>
using namespace std;

struct A1 {
  static const int _AINT = 0;
};

struct A2 {
  static const int _AINT = 1;
};

template< class T >
struct B{
  void Fun(){
    if ( T::_AINT == 1 ) {
      cout << "TADA!";
    }
  };
};

int main(void){
  B< A1 > b1;
  B< A2 > b2;
  b1.Fun();
  b2.Fun();
  return 0;
};
William Hemsworth 1,339 Posting Virtuoso

The problem is easy to solve, instead of adding a new line to the text box, simply add the line to a global string, then assign the string to the textbox.

#include <windows.h>
#include <iostream>

HWND hEdit; // Text Box
std::string log;

void AddLogLine(char *line) {
  log += line;
  log += "\n";
  SetWindowText( hEdit, log.c_str() );
}

/* Rest of the Code *

You could also consider using a Listbox instead.

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

That is a well known link for learning the Win32 API. For your original question, there's not much more you could need that's not already on that page.

William Hemsworth 1,339 Posting Virtuoso

It's all here.

William Hemsworth 1,339 Posting Virtuoso

Either change the style of the window, or add this to your windows procedure:

case WM_GETMINMAXINFO:
  {
    MINMAXINFO *mmi = (MINMAXINFO*) lParam;
    mmi->ptMinTrackSize.x = mmi->ptMaxTrackSize.x = 500; // Width
    mmi->ptMinTrackSize.y = mmi->ptMaxTrackSize.y = 500; // Height
  }
  break;

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

Add this message handler to your windows proc:

case WM_PAINT:
  {
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint( hwnd, &ps );
    TextOut( hdc, 0 /* X */, 0 /* Y */, "Blah de blah de blah", 20 /* Number of chars */);
    EndPaint( hwnd, &ps );
  }
  break;

Should be enough to get you started - though google would have been even better.

William Hemsworth 1,339 Posting Virtuoso

It's an easy problem, just remember to split it up into parts.


>The program should ask the user how much the pallet weights by itself
First, make a program.

#include <iostream>

int main() {
}

Now, allow the user to input the weight of the pallet.

#include <iostream>

int main() {
  float palletWeight;
  std::cout << "Enter pallet weight: ";
  std::cin >> palletWeight;
}

There, that's one step done.

Now, try the next step. The same as I have just shown you. But this time..."with the widgets stacked on it". Make another variable with the type float, perhaps called totalWeight, then allow the user to input the total weight using std::cin.

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

Hey David A. Newbie, use code-tags in future.

William Hemsworth 1,339 Posting Virtuoso

I would probably try and solve this by reading all the data into an array of chars, and then manually splitting up the text. You should have more control over whats happening if you do this. See my code snippet. As for converting to an int, it's no big task, you can either use std::stringstream, or use the C function atoi (which I would probably use as it's easier).
You can do as niek said, split up all the text into lines, and then split up the lines to retrieve the data you need.

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

What your trying to do with trimleft will only work with a reference to a pointer which is pointing at an array of chars, like this:

void trimLeft(char *&a)
{
  while (*a++ == ' ');
  a--;
}


int main() {
  char a[11] = "  smith";
  char *ptr = a;
  trimLeft(ptr);
  cout << ptr << endl;
}

You must realize that no data has been moved at all, however ptr is just pointing to a different part of the array you created to begin with. If you want to actually alter the array of characters, you will have to do something similar to what Ancient Dragon mentioned.

edit: I guess this thread should be moved to the C++ forum now ;)

William Hemsworth 1,339 Posting Virtuoso

>maybe I should just return the default constructor for T?
You could do that, and add a parameter for the caller to check if anything was found, like this:

template <class T>
T find(char x, T array[], bool &found){
  string str = "hello";
  found = true;
  for(int i = 0; i < str.length(); i++){
     if(x == str[i]) return array[i];
  }
  found = false;
  // Return default constructor
}
William Hemsworth 1,339 Posting Virtuoso

Maybe return an index or value that will never be used, for example, if T = int, return (-1 for example), and then the caller can do a check to see if a value was found, if not, -1 is returned.

William Hemsworth 1,339 Posting Virtuoso

Try using your head, or even a search engine. Link

William Hemsworth 1,339 Posting Virtuoso

FindWindow will only return a handle to one window, to do this you will have to loop through all opened applications and hide them one at a time. Try looking up the EnumWindows function, it may provide your solution.

William Hemsworth 1,339 Posting Virtuoso
void swapLines(int j, int k)
{
  char *temp = malloc(sizeof(char) * 1000);
  temp = strings[j]; // What happened to the 1000 chars you just allocated?
  strings[j] = strings[k];
  strings[k] = temp;
}

Memory leak!

Remember to free any data you allocate using the free function.

William Hemsworth 1,339 Posting Virtuoso

Try this instead:

//empresas[i].nome_empresa = "a string";
strcpy( empresas[i].nome_empresa, "a string" );
William Hemsworth 1,339 Posting Virtuoso

>I guess blocking input might be a bad idea since then you have no way of using the ctrl
Well, I still have the right control key on my keyboard.

But the point I was making is, in my keyboard hook, I made it so windows completely ignores that the control key was ever pressed, so no need to send the release key message, but for some reason... it didn't work, which is why i'm going to try Block Input :)

William Hemsworth 1,339 Posting Virtuoso

I will take your advice, and improve it. But cut me some slack :icon_lol: ...
I made this when I was 14 I think, didn't seem too bad at the time. XD

As for the control key always being left on, I could never quite figure out why that was happening, the keyboard hook stopped windows from processing it. I will try Block Input though, hopefully this is still helping chrischavez solve his problem (as well as mine) :D .

William Hemsworth 1,339 Posting Virtuoso

To begin with, I created a windows hook for the keyboard. This enables you to catch messages related to the keyboard and handle them before windows does.

bool ld = 0, // Left button down
rd = 0,      // Right button down
ud = 0,      // Up button down
dd = 0,      // Down button down
lcd = 0;     // Left Control key down

These are flags to show if any of the arrow keys or the left control key is being pressed, they are kept up to date in the keyboard hook.

I also set up a timer in the main windows message loop with an interval of 5ms. So every 5ms it checks if any of the arrow keys are down, if any of them are, then it will change the velocity the cursor is moving in the appropriate direction.

case WM_TIMER:
{

  // Check if keys are down
  if (ld) vx -= cursorSpeed;  // Left key
  if (rd) vx += cursorSpeed;  // Right key
  if (ud) vy -= cursorSpeed;  // Up key
  if (dd) vy += cursorSpeed;  // Down key

  GetCursorPos(&mousePos);

  // Add velocity to current coordinates
  x += vx;
  y += vy;

  // Slows the velocity of the cursor down
  vx *= cursorFriction;
  vy *= cursorFriction;

  // Calculate the average speed
  avSpeed = sqrt( vx * vx + vy * vy );

  if (avSpeed > 0.2) {
    // If cursor isn't almost stopped
    SetCursorPos(x, y);

  } else {
    // Allow user to move …
William Hemsworth 1,339 Posting Virtuoso

I made the same program once, but much more complex. In the end I used a similar technique to what Freaky_Chris mentioned, though I went the extra mile and added velocity & friction to make it look a little smoother.
On top of that, it allowed the user the left click using only the keyboard. I originally made this for a friend who had a problem and wasn't able to use his mouse, so I realize it might be slightly buggy in some areas, but overall it works pretty well.

I've attached the project & executable, it might help you improve yours. Move the cursor with the arrow keys, and use the left ctrl button to emulate a left click. You can change the options by right clicking on the notification icon (picture of a cursor) in your task bar.

Hope this helps :)

William Hemsworth 1,339 Posting Virtuoso

This question seems suspisiously similar to this one?

William Hemsworth 1,339 Posting Virtuoso

>Feel free to show me a better way that pauses the execution screen that pops up so that i can check for debugging purposes.

I just did :icon_confused:


>Site rules "CODE TAGS".

I see you decided to ignore that rule then?

William Hemsworth 1,339 Posting Virtuoso

Why people insist on using system("pause") I just don't know, especially when you can just use cin.get() or cin.ignore() If you insist on having a function thats identical, here you go ;) :

#include <iostream>
#include <windows.h>

void Pause(char *message = "Press any key to continue . . . ") {
  std::cout << message;
  HANDLE hStdin; 
  DWORD cNumRead; 
  INPUT_RECORD irInBuf[1]; 

  if ( HANDLE(hStdin = GetStdHandle( STD_INPUT_HANDLE )) == INVALID_HANDLE_VALUE )
    return;

  while ( true )  { 
    if (! ReadConsoleInput( hStdin, irInBuf, 1, &cNumRead) )
      return;

    for (DWORD i = 0; i < cNumRead; ++i)
      if ( irInBuf[i].EventType == KEY_EVENT && irInBuf[i].Event.KeyEvent.bKeyDown ) {
        std::cout << '\n';
        return;
      }
  }
}

But, just stick to cin.ignore() :icon_cool:

William Hemsworth 1,339 Posting Virtuoso

>There's nothing inherently wrong with returning a duplicated copy of the string in allocated memory

I will agree with that to some extent :icon_wink: but only if the caller knows exactly what he's doing, as by doing this, it makes your code more prone to errors. I'm quite sure it's bad practice to do this as i've caused myself problems in the past with memory leaks. One of my most common mistakes was something similar to this:

char *SubString(char *str, int beg, int fin) {
  char *sub = (char*)malloc( fin - beg + 1 );
  // Rest of the code
  return sub;
}

int main() {
  // Oops
  someFunction( SubString("abcdef", 2, 4) );
}

It's better to be safe than sorry in my opinion :icon_cheesygrin:

William Hemsworth 1,339 Posting Virtuoso

return strdup(temp); Bad idea, you should never return a pointer to allocated dynamic memory, as you can quite easily forget to release that memory once you've done with it. The correct way to do this is to add a parameter containing a pointer to a buffer which you can write to.

Instead of this:

char *getline(FILE *input)
{
  char temp[MAX_LEN];
  fgets(temp,MAX_LEN,input);
  temp[strlen(temp)-1]='\0';
  return strdup(temp);
}

Try:

int getline(FILE *input, char *ptr, int destSize)
{
  char temp[MAX_LEN];
  /* wanted MAX_LEN of data, is there something to read? */
  if (fgets(temp, MAX_LEN, input) != NULL) {
    size_t net_len = strlen(temp) -1;

    /* trim the newline/return if it's there */
    if (temp[net_len] == '\n') {
      temp[net_len] = '\0';
    }
  } else {
    /* handle the error... */
  }
  strcpy_s(ptr, destSize, temp);
}

Hope this helps :icon_cheesygrin:

William Hemsworth 1,339 Posting Virtuoso

You can't do it the way your hoping to, but with some simple casting, it can be achived.

MyClass<char> mc1;
MyClass<int> mc2;
MyClass<float> mc3;

void *arr[3];
arr[0] = reinterpret_cast<void*>( &mc1 );
arr[1] = reinterpret_cast<void*>( &mc2 );
arr[2] = reinterpret_cast<void*>( &mc3 );

And, to then use an item from the array, you can do the following:

// void someFunction(MyClass<int>*)
someFunction( reinterpret_cast<MyClass<int>*>(arr[1]) );

Hope this helps :icon_lol:

William Hemsworth 1,339 Posting Virtuoso

hehe :)

William Hemsworth 1,339 Posting Virtuoso

'\n' is simply equivalent to a newline, you could have easily replaced it outside the qoutes as endl as you have done with the other lines if you had wanted.. it was just easier to do that :icon_wink: .

William Hemsworth 1,339 Posting Virtuoso

Woo! you did it without anybody writing the code for you.. (it's a nice change)
but, here are just a few final touches to it.. along with formatting it for you (for the second time)

#include <iostream> 
using namespace std; 

int add(int x, int y) {
  int r;
  r = x + y;
  return(r); 
}  

int main () { 
  int x, y;

  cout << "Welcome to the Functions Program! To quit enter 0." << endl;
  cout << "Input two numbers." << endl;
  cin >> x >> y;

  while (x != 0 || y != 0) {
    int [B]z = add(x, y);[/B] 
    cout << "The result is " << z;  
    cout << "[B]\n[/B]Would you like to continue? If so enter another two numbers, if not enter 0" << endl;
    cin >> x >> y ; 
  }
}
Alex Edwards commented: Yes! Whoo Indeed! O_O +5
William Hemsworth 1,339 Posting Virtuoso

A good effort :) (except for some of the formatting)
On line 23, would it be better to just replace that while with an if, as that way it will not run into an endless loop printing the result?

Change it from this: while (x != 0 || y != 0) { to: if (x != 0 || y != 0) { Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

When things get this bad, honestly, just start over.
http://www.cplusplus.com/doc/tutorial/
Understand how to use functions and make simple expressions, also, keep your code well formatted. Here is how your current code would look well formatted, but all the mistakes are still there.

#include<iostream> 
using namespace std; 

int add(int x, int y) // your missing something here..

int main () 
{ 
  int x, y;
  cout << "Welcome to the Functions Program! To quit enter 00." << endl;
  cout << "Input two numbers." << endl;
  cin >> x, y;

  while (x != 00 || y != 00) // Padding with extra 0 changes the number base to octal, which I doubt you need here
  {
    int z; 
    z = add(x,y); 
    cout << "The result is " << z; 
    return 0; // Whats the point in the while loop, if this is here
  }

  int add(int x, int y) 
  {
    return (x+y); 
  } 
}

I have highlighted your mistakes, see if you can fix them.

Alex Edwards commented: Whoo! =) +5
Salem commented: Yeah, gotta watch those octal zeros, they're a lot smaller than the decimal equivalents ;) +23
William Hemsworth 1,339 Posting Virtuoso

double doesn't support the Modulus operator, you will have to implement it yourself if you want to do this.

William Hemsworth 1,339 Posting Virtuoso

How about this, rather unusual method ;)

#include <iostream>

struct octet {
  union {
    char val;
    struct {
      unsigned h : 1;
      unsigned g : 1;
      unsigned f : 1;
      unsigned e : 1;
      unsigned d : 1;
      unsigned c : 1;
      unsigned b : 1;
      unsigned a : 1;
    };
  };
};

int main() {
  bool bits[] = {0, 1, 1, 0, 0, 0, 0, 1};

  octet o;
  o.a = bits[0];
  o.b = bits[1];
  o.c = bits[2];
  o.d = bits[3];
  o.e = bits[4];
  o.f = bits[5];
  o.g = bits[6];
  o.h = bits[7];

  std::cout << o.val; // 01100001 = 'a'
  std::cin.ignore();
}

Theres practically no maths involved :)

William Hemsworth 1,339 Posting Virtuoso

>Deliberately crashing the kernel isn't funny
Does that mean accidently crashing it is? :)

Hah :D , sorry, I coulden't help myself.

Alex Edwards commented: Whoo! =P +5
William Hemsworth 1,339 Posting Virtuoso

>I was just curious, I absolutely do not want to make any type of virus, trojan, or malware.

I have to admit, I believe you (because i've helped you in many previous threads). And well, we all find ammusment in differen't things, making pranks for a friend (as long as it doesn't damage their system like Duoas said) isn't too bad if it gives a couple of laughs. It will be possible, but I don't know any ways of doing it off the top of my head. Just.. don't over-do it :)

William Hemsworth 1,339 Posting Virtuoso

Your problem is very small :) The coordinate in which you are trying to display the menu is not based on the client location. Change your WM_RBUTTONUP message like this:

case WM_RBUTTONUP: 
   POINT p;
   p.x = LOWORD(lParam);
   p.y = HIWORD(lParam);
   ClientToScreen(hWnd, &p);
   DisplayPopupMenu(p.x, p.y);
   break;

Hope this helps.

William Hemsworth 1,339 Posting Virtuoso

Maybe this thread will help you :) Link

William Hemsworth 1,339 Posting Virtuoso

be thankful :) , email subscriptions don't even work for me ;o

William Hemsworth 1,339 Posting Virtuoso

What annoys me more is the dumb Smily Central thing, every time I hover my mouse over it, I get the annoying disruptive "hellooooooo" sound..

William Hemsworth 1,339 Posting Virtuoso

>make a simple program
If its so simple, why can't you do it?, or at least make an attempt at it.
All you need to know to be able to do this, is how to use nested loops and from there i'm sure you could figure it out yourself.

William Hemsworth 1,339 Posting Virtuoso

If you want to remove mutliple characters from the array, you can simply change it like this.

#include <iostream>

// Returns true if text contains ch
inline bool contains(char *text, char ch) {
   while (*text) {
      if (*text++ == ch) {
         return true;
      }
   }
   return false;
}

int main() {
   char arr[] = "abc  \n   \t\ndef";
   char spaces[] = " \t\n";

   // Create another array the same length as arr
   char temp[sizeof arr];

   // Index of where to insert character in new array
   int temp_index = 0;

   // Loop through each character until null-terminator is reached
   for (int i = 0; arr[i]; ++i) {
      if (!contains(spaces, arr[i])) {
         // Character isn't in the spaces array
         temp[temp_index++] = arr[i];
      }
   }

   // Add null-terminator
   temp[temp_index] = '\0';

   // Replace old array with new one
   strcpy_s(arr, sizeof(arr), temp);

   // Display the array
   std::cout << arr; // Outputs "abcdef"

   // Pause
   std::cin.ignore();
   return 0;
}

Now this will check to see if any of the char's in arr contain any of the char's in spaces, if it does, then it will remove them from the arr array.

William Hemsworth 1,339 Posting Virtuoso

Portability isn't too important when it comes to making a quick speed test, as I woulden't be keeping it that way. Either way, if the code didn't compile for you, I posted my output :)

>Depends. Maintainability (and readability) are pretty important in the real-world.
Thats true

William Hemsworth 1,339 Posting Virtuoso

ninwa's solution uses the same technique as mine, but using std::string's instead. Though it might be a better idea, it may overall be slower. Just to check, I did I little test.

ninwa's version:

#include <iostream>
using namespace std;

typedef unsigned __int64 uint64;

inline __declspec(naked) uint64 GetCycleCount() {
    _asm rdtsc;
    _asm ret;
}

int main() {
   uint64 cycle_timer_beg;
   uint64 cycle_timer_end;

   cycle_timer_beg = GetCycleCount();

   for (int j = 0; j < 10000; ++j) {

         char arr[] = {'a', 'b', 'c', ' ', ' ', ' ',
                       ' ', ' ', 'd', 'e', 'f', '\0'};
         string s(arr);
         string tmp = "";
         for (int i = 0; i < s.length(); i++) {
            if (s.at(i) != ' ') {
               tmp += s.at(i);
            }
         }
         s = tmp;

   }

   cycle_timer_end = GetCycleCount();

   cout << "Average cycle count: " << ((cycle_timer_end - cycle_timer_beg) / 10000);
   cin.ignore();
   return 0;
}

My version:

#include <iostream>
using namespace std;

typedef unsigned __int64 uint64;

inline __declspec(naked) uint64 GetCycleCount() {
    _asm rdtsc;
    _asm ret;
}

int main() {
   uint64 cycle_timer_beg;
   uint64 cycle_timer_end;

   cycle_timer_beg = GetCycleCount();

   for (int j = 0; j < 10000; ++j) {

      char arr[] = "abc     def";
      char temp[sizeof arr];
      int temp_index = 0;
      for (int i = 0; arr[i]; ++i) {
         if (arr[i] != ' ') {
            temp[temp_index++] = arr[i];
         }
      }
      temp[temp_index] = '\0';
      strcpy_s(arr, sizeof(arr), temp);

   }

   cycle_timer_end = GetCycleCount();

   cout << "Average cycle count: " << ((cycle_timer_end - cycle_timer_beg) / 10000);
   cin.ignore();
   return 0;
}

Hopefully this isn't going over the …

William Hemsworth 1,339 Posting Virtuoso

Well, a simple way to achieve this would be to create another array, the same length as arr, go through each character, and if that character isn't a space then copy it to the second array. Like this.

#include <iostream>

int main() {
   char arr[] = "abc     def";

   // Create another array the same length as arr
   char temp[sizeof arr];

   // Index of where to insert character in new array
   int temp_index = 0;

   // Loop through each character until null-terminator is reached
   for (int i = 0; arr[i]; ++i) {
      if (arr[i] != ' ') {
         // Character isn't a space
         temp[temp_index++] = arr[i];
      }
   }

   // Add null-terminator
   temp[temp_index] = '\0';

   // Replace old array with new one
   strcpy_s(arr, sizeof(arr), temp);

   // Display the array
   std::cout << arr;

   // Pause
   std::cin.ignore();
   return 0;
}

But if you wanted to achieve this without the need of a second array, its going to require a more complex algorithm. Hope this helps, and I also hope I haven't given too much away :)

William Hemsworth 1,339 Posting Virtuoso

>Well personally I think its better suited than std::vector
Ignoring that valarray is designed for numeric types, and ignoring that you can't use the majority of operations with valarray on std::string, and ignoring that you've lost nearly all benefits of the standard library by using a ******* child of the standardization process, and ignoring that the standard definition is broken and many implementations of valarray are substandard because nobody cares enough to fix it in light of exression templates, it probably is better suited. But only for your specific example, and only after ignoring numerous rather large turds that you'll end up eating later.

Fair enough :icon_cheesygrin:

William Hemsworth 1,339 Posting Virtuoso

Well personally I think its better suited than std::vector, and I think its too much trouble to dynamically allocate and delete an array of strings, so I think its a nice solution :]