{ Learn Code. Share Code. Teach Code. Love Code. }

  • Random line read

  • Post your questions regarding programming in C++ in here.
Post your questions regarding programming in C++ in here.
 #78801  by MrAlicard
 Wed Nov 20, 2013 8:08 pm
Hello
I want to solve it randomly reads the lines.
I found a source code, but it will crash the program.

This is source code:
Code: Select all
DWORD cFindEvent::GetRandomPosition()
{
   //---------------------------------------------------------------------------------------
   FILE * garew = fopen (MobCoords,"r");
   //---------------------------------------------------------------------------------------
   char temp[1024];
   int i = 0;
   int j = 0;
   int licz = rand() % 100;
   //---------------------------------------------------------------------------------------
   while ( !feof(garew) && i <= licz)
   {
      //-----------------------------------------------------------------------------------
      fgets(temp , 1024 , garew );
      //-----------------------------------------------------------------------------------
      if(temp[0] != '/' && temp[1] != '/')
      {
         //-------------------------------------------------------------------------------
         sscanf(temp,"%d %d %d", &DayMap, &DayX, &DayY);
            if(DayMap >= 0)
         {
            //---------------------------------------------------------------------------
            i++;
            //---------------------------------------------------------------------------
         }
         //-------------------------------------------------------------------------------
      }
      //-----------------------------------------------------------------------------------
   }
   //---------------------------------------------------------------------------------------
   fclose(garew);
   //---------------------------------------------------------------------------------------
   FILE * garew2 = fopen (MobCoords,"r");
   //---------------------------------------------------------------------------------------
   if(licz > i)
   {
      //-----------------------------------------------------------------------------------
      int licz2 = rand() % i;
      //-----------------------------------------------------------------------------------
      while ( j <= licz2 )
      {
         //-------------------------------------------------------------------------------
         fgets(temp , 1024 , garew2 );
         //-------------------------------------------------------------------------------
         if(temp[0] != '/' && temp[1] != '/')
         {
            //---------------------------------------------------------------------------
            sscanf(temp,"%d %d %d", &DayMap, &DayX, &DayY);
            if(DayMap >= 0)
            {
               //-----------------------------------------------------------------------
               j++;
               //-----------------------------------------------------------------------
            }
            //---------------------------------------------------------------------------
         }
         //-------------------------------------------------------------------------------
      }
      //-----------------------------------------------------------------------------------
   }
   //---------------------------------------------------------------------------------------
   fclose(garew2);
   //---------------------------------------------------------------------------------------
    DWORD Reward = DNState.DayBossIndex=CreateMobInXY(21,DayMap,DayX,DayY);
   Chat.MessageAll(0,0,NULL,"The monster entered the coordinates: %d x %d", DayX, DayY);;
   //---------------------------------------------------------------------------------------
   return Reward;
   //---------------------------------------------------------------------------------------
}
Txt file content:
Code: Select all
0 63 120 
0 63 125 
0 70 140
What's wrong with this?
 #78803  by comathi
 Wed Nov 20, 2013 10:17 pm
I don't know much about C++, but it seems to me the error might be in your fopen() function:
Code: Select all
fopen (MobCoords,"r")
According to the C++ reference, the first parameter of fopen() has to be a Char variable, such as "filename.txt".

I'm assuming MobCoords is a variable? Where in your code is that variable located... if it doesn't exist, you may have your problem right there lol
 #78804  by MrAlicard
 Thu Nov 21, 2013 6:29 am
comathi wrote:I don't know much about C++, but it seems to me the error might be in your fopen() function:
Code: Select all
fopen (MobCoords,"r")
According to the C++ reference, the first parameter of fopen() has to be a Char variable, such as "filename.txt".

I'm assuming MobCoords is a variable? Where in your code is that variable located... if it doesn't exist, you may have your problem right there lol
This has included:
Code: Select all
#define MobCoords             "..\\Config\DayCoords.txt"

int DayMap;
int DayX;
int DayY;
int DayBossIndex;
 #78805  by comathi
 Thu Nov 21, 2013 9:51 am
The filename looks wrong.

If you're trying to access a file in the parent (previous) folder, it should be
Code: Select all
"..\Config\DayCoords.txt"
I think you've got one too many backslashes at the beginning ;)
 #84359  by MrMichael
 Sun Mar 11, 2018 7:11 pm
Here's a piece of code written in C++ which might help you.
Code: Select all
#include <iostream>
#include <string>
#include <fstream>
#include <time.h>

int main()
{
    const std::string fileName = "path/to/file.extension";

    // first, never forget to seed the number generator
    // if you didn't do it already
    srand(time(NULL));

    // open the file
    std::ifstream file(fileName);
    if (file.is_open())
    {
        // lets count the total number of lines
        int linesCount = 0;
        std::string line;
        while (std::getline(file, line))
        {
            ++linesCount;
        }

        // reopen the file
        file.close();
        file.open(fileName);

        // pick a random line
        // tip: don't use rand(), check on the internet for 
        // randomness in C++11
        const int randomLine = rand() % linesCount;

        // read lines until we reach our desired random line
        for (int crtLine = 0; crtLine <= randomLine; ++crtLine)
        {
            std::getline(file, line);
        }

        // use the line here
        int iDayMap = 0;
        int iDayX = 0;
        int iDayY = 0;
        sscanf(line.c_str(), "%d %d %d", &iDayMap, &iDayX, &iDayY);

        // line is our std::string object
        // line.c_str() returns a const char* string
        // which can be used with sscanf
        // another tip: if available, use sscanf_s, which should be more secure
        // than sscanf, but if that is no concern, you can use sscanf
        // sscanf_s(line.c_str(), "%d %d %d", &iDayMap, &iDayX, &iDayY);
    }
}
A few tips:
  1. As I said in the comments of the code, you should not use srand() and rand(). I did it just to make it simple.
  2. If you plan in getting random lines a lot of times, do not open and read the file everytime. Consider reading once, add them in a vector then everytime you need a random line, get it from the vector. You have everything there, including the lines count (the size of vector). Even better: made a struct with the 3 variables (iDayMap, iDayX, iDayY), and add those in the vector. This way, you won't have to do sscanf everytime. It will be faster.
  3. Avoid defines (except include guards)
  4. Try to define paths using / (forward slash) instead of \ (back slash) because of character escaping. It is easier, and works on every platform.